首頁 web前端 js教程 JavaScript中的普通函數與建構子比較_javascript技巧

JavaScript中的普通函數與建構子比較_javascript技巧

May 16, 2016 pm 04:05 PM
普通函數 建構函數

問題

什麼是建構子?
構造函數與普通函數區別是什麼?
用new關鍵字的時候到底做了什麼?
建構函數有回傳值怎麼辦?
構造函數能當普通函數呼叫嗎?

以下是我的一些理解,理解錯誤的地方懇請大家幫忙指正,謝謝!

this
this永遠指向目前正在被執行的函數或方法的owner。例如:

function test(){
  console.log(this);
}
test();
//Window {top: Window, window: Window, location: Location, external: Object, chrome: Object…}
登入後複製

上面這段程式碼中,我們在頁面中定義了一個test()函數,然後在頁面中呼叫。函數定義在全域時,其owner就是目前頁面,也就是window物件。

this指向的幾種情況

1.全域中呼叫

    this.name //this指向window物件
   
2.函數呼叫

    test();//test()函數中的this也指向window物件
   
3.物件的方法呼叫

    obj1.fn();//obj1物件的fn()方法中的this指向obj1
   
4.呼叫建構子
    var dog=new Dog();//建構子內的this指向新創建的實例對象,也就是這裡的dogcall和apply

call和apply的作用一樣,只是接受參數的方式不一樣,call接受的是多個單一參數,apply接受的是參數陣列。
call和apply的作用簡單地可以說成,當一個物件實例缺少一個函數/方法時,可以呼叫其他物件的現成函數/方法,其方式是透過取代其中的this為這個物件實例,改變函數運行時的上下文。
例如:

function Dog(){
  this.sound="汪汪汪";
}
Dog.prototype.bark=function(){
  alert(this.sound);
}
登入後複製

現在我有另一個cat物件:

var cat={sound:'喵喵喵'}

我也想讓這個cat物件可以呼叫bark方法,這時候就不用重新為它定義bark方法了,可以用call/apply呼叫Dog類別的bark方法:

Dog.prototype.bark.call(cat);

或:

dog.bark.call(cat);

加點東西,變成一個帶有參數的栗子:

function Dog(){
  this.sound="汪汪汪";
}
Dog.prototype.bark=function(words){
  alert(this.sound+" "+words);
}
var dog=new Dog();
dog.bark("有小偷");//alert:汪汪汪  有小偷
Dog.prototype.bark.call(cat,"饿了");//alert:喵喵喵  饿了
登入後複製

普通函數
這是一個簡單的普通函數:

function fn(){
  alert("hello sheila");
}
fn();//alert:hello sheila
登入後複製

普通函數與建構子比較有四個明顯特點:

1.不需要用new關鍵字呼叫

    fn();2.可以用return語句回傳值

 function fn(a,b){
    return a+b;
  }
  alert(fn(2,3));//alert:5
登入後複製

3.函數內部不建議使用this關鍵字
我們說不建議使用,當然硬要用是可以的,只是要注意這時候發生了什麼事。如果在普通函數內部使用this關鍵字定義變數或函數,因為這時候this指向的是window全域對象,這樣無意間就會為window添加了一些全域變數或函數。

function greeting(){
    this.name="sheila";
    alert("hello "+this.name);
  }
  greeting();//alert:hello sheila
  alert(window.name);//alert:sheila
登入後複製

4.函數命名以駝峰方式,首字母小寫

建構子
在JavaScript中,用new關鍵字來呼叫定義的建構子。預設回傳的是一個新對象,這個新對象具有建構函數定義的變數和函數/方法。

舉個栗子:

function Prince(name,age){
  this.gender="male";
  this.kind=true;
  this.rich=true;
  this.name=name;
  this.age=age;
}
Prince.prototype.toFrog=function(){
  console.log("Prince "+this.name+" turned into a frog.");
}
var prince=new Prince("charming",25);
prince.toFrog();//Prince charming turned into a frog.
prince.kind;//true
登入後複製

与普通函数相比,构造函数有以下明显特点:

1.用new关键字调用

var prince=new Prince("charming",25);

2.函数内部可以使用this关键字
在构造函数内部,this指向的是构造出的新对象。用this定义的变量或函数/方法,就是实例变量或实例函数/方法。需要用实例才能访问到,不能用类型名访问。

prince.age;//25
Prince.age;//undefined

3.默认不用return返回值
构造函数是不需要用return显式返回值的,默认会返回this,也就是新的实例对象。当然,也可以用return语句,返回值会根据return值的类型而有所不同,细节将在下文介绍。

4.函数命名建议首字母大写,与普通函数区分开。
不是命名规范中的,但是建议这么写。

使用new关键字实例化的时候发生了什么?
以上文中的Prince()函数举个栗子:

1.第一步,创建一个空对象。

var prince={}

2.第二步,将构造函数Prince()中的this指向新创建的对象prince。
3.第三步,将prince的_proto_属性指向Prince函数的prototype,创建对象和原型间关系
4.第四步,执行构造函数Prince()内的代码。

构造函数有return值怎么办?
构造函数里没有显式调用return时,默认是返回this对象,也就是新创建的实例对象。
当构造函数里调用return时,分两种情况:

1.return的是五种简单数据类型:String,Number,Boolean,Null,Undefined。
这种情况下,忽视return值,依然返回this对象。

2.return的是Object
这种情况下,不再返回this对象,而是返回return语句的返回值。

function Person(name){
    this.name=name;
    return {name:"cherry"}
  }
  var person=new Person("sheila");
  person.name;//cherry
  p;//Object {name: "cherry"}
登入後複製
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

es6中箭頭函數和普通函數的差別是什麼 es6中箭頭函數和普通函數的差別是什麼 Mar 08, 2022 pm 12:11 PM

區別:1、箭頭函數的定義要比普通函數定義簡潔、清晰得多,很快捷;2、箭頭函數不會創建自己的this,而普通函數會;3、箭頭函數不能作為構造函數使用,而箭頭函數能作為建構函數使用;4、箭頭函數沒有自己的arguments,而箭頭函數有。

Python中的建構函數 Python中的建構函數 Sep 02, 2023 pm 04:29 PM

在Python中,每個類別都有一個建構函數,它是類別內部指定的特殊方法。建構函數/初始化程序將在為類別建立新物件時自動呼叫。當物件被初始化時,建構函數將值指派給類別中的資料成員。沒有必要明確定義建構函數。但為了創建建構函數,我們需要遵循以下規則-對於一個類,它只允許有一個建構函數。建構函式名稱必須是__init__。必須使用實例屬性定義建構函式(只需將self關鍵字指定為第一個參數)。它不能傳回除None之外的任何值。語法classA():def__init__(self):pass範例考慮下面的範例並

C++語法錯誤:相同的建構函式簽章出現多次,該怎麼解決? C++語法錯誤:相同的建構函式簽章出現多次,該怎麼解決? Aug 22, 2023 pm 04:49 PM

C++是一門強大的程式語言,但在使用過程中,難免會遇到各種問題。其中,相同的建構函式簽章出現多次就是一種常見的語法錯誤。本文將介紹這種錯誤的原因和解決方法。一、錯誤原因在C++中,建構函式用來建立物件時初始化物件的資料成員。但是,如果在同一個類別中定義了相同的建構函式簽章(即參數型別和順序相同),編譯器就無法確定要呼叫哪一個建構函數,進而造成編譯錯誤。例如,

go語言有建構子嗎 go語言有建構子嗎 Jan 10, 2023 pm 02:15 PM

go語言沒有建構子。 go語言作為結構化的語言是沒有物件導向語言中的建構方法的,不過可以透過一些方式實現類似的物件導向語言中建構方法的效果,也就是使用結構體初始化的過程來模擬實現構造函數。

C++語法錯誤:定義在類別外的建構子必須加上類別名稱作為限定符,該怎麼改正? C++語法錯誤:定義在類別外的建構子必須加上類別名稱作為限定符,該怎麼改正? Aug 22, 2023 pm 02:00 PM

C++是一種廣泛使用的物件導向程式語言,C++中定義類別的建構函式時,如果希望將建構函式的定義放在類別外部,那麼就需要在建構函式的定義中加上類別名稱作為限定符,以指定這個建構函式是屬於哪個類別的。這是C++語法的一條基本規定。如果在定義類別的建構子時沒有遵守這個規定,就會出現編譯錯誤,提示「定義在類別外的建構子必須加上類別名稱作為限定符」。那麼,如果碰到這種編譯錯誤,應該

什麼是構造函數?詳解JavaScript中的建構函數 什麼是構造函數?詳解JavaScript中的建構函數 Aug 04, 2022 pm 03:22 PM

作為原型和原型鏈的基礎,先了解清楚構造函數以及它的執行過程才能更好地幫助我們學習原型和原型鏈的知識。這篇文章帶大家詳細了解JavaScript中的建構函數,介紹一下怎麼利用建構函數來建立一個js對象,希望對大家有幫助!

箭頭函數和普通函數的區別 箭頭函數和普通函數的區別 Sep 13, 2023 am 09:32 AM

箭頭函數和普通函數的差異主要在語法簡潔性、this指向不同、不適用於建構子、無arguments物件等。詳細介紹:1、語法簡潔性,箭頭函數的語法相對於普通函數更加簡潔,箭頭函數可以使用箭頭來定義,省略了function關鍵字和花括號,可以直接定義函數的參數和返回值,箭頭函數在只有一個參數的情況下,還可以省略括號;2、this指向的不同等等。

C++報錯:建構子必須在public區域聲明,怎麼處理? C++報錯:建構子必須在public區域聲明,怎麼處理? Aug 21, 2023 pm 08:26 PM

在C++程式設計中,建構子是用來初始化類別的成員變數的重要函式。它在創建物件時自動調用,以確保物件的正確初始化。建構子必須在類別中聲明,但是有時會遇到錯誤提示「建構子必須在public區域宣告」。這個錯誤通常是因為建構函式的存取權限修飾符錯誤所引起的。在C++中,類別的成員變數和成員函數都有一個存取權限修飾符,包括public、private和protected。

See all articles