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

來源:互聯網
上載者:User

問題

什麼是建構函式?
建構函式與普通函數區別是什嗎?
用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.第一步,建立一個Null 物件。

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"}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.