首頁 >web前端 >js教程 >javascript建構函數的深入探討

javascript建構函數的深入探討

不言
不言轉載
2018-11-17 15:23:282318瀏覽

這篇文章帶給大家的內容是關於javascript建構函數的深入探討,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

我們相約在今天,在今天討論javascript建構函數,感謝你如約而至

#我們昨天前幾天討論過構造函數constructor,得出了結論

constructor是原型物件上的一個屬性,預設指向這個原型的建構子

這個結論貌似對我們平時的工作中似乎並沒有什麼用處,那構造函數,就真的沒什麼用嗎?

使用建構子建構可以重複使用的物件

JS中的函數即可以是建構子又可以當作普通函數來調用,當使用new來建立物件時,對應的函數就是建構函數,透過物件來呼叫時就是普通函數。

在我們平常工作中,常常會需要我們創建一個對象,而我們更多的是使用對像直接量,直接創建,舉個栗子,程式碼如下

var person = {
    name:'postbird',
    address:'earth',
    sayHello:function(){console.log('Hello,I am ' + this.name);}
};

如果只是一個單獨的對象,對象的屬性和方法基本上不會變了,這麼玩完全可以,但是如果你的對像有很多實例,或者涉及繼承或者構造函數傳參,留意代碼註釋

//创建了一个构造函数
function Person(name,address){
    this.name = name;
    this.address = address;
}
//为构造函数的原型对象添加一个方法sayHello
Person.prototype.sayHello = function(){
    console.log('Hi I am ' + this.name);
}
//通过构造函数Person实例化一个p1,并传参
var p1 = new Person('postbird','earth');
//通过构造函数Person实例化一个p2,并传参
var p2 = new Person('ptbird','month');
console.log(p1);//{name: "postbird", address: "earth"}
console.log(p2);//{name: "ptbird", address: "month"}
// p1和p2 继承了Person的sayHello方法
p1.sayHello()//Hi I am ptbird
p2.sayHello()//Hi I am postbird

耐心品位上面的程式碼,這樣的可擴展性就會更好,可以創N個實例,實現程式碼復用

經典案例

關於js的constructor構造函數,有一個很經典的demo

function Person(area){
  this.type = 'person';
  this.area = area;
}
Person.prototype.sayArea = function(){
  console.log(this.area);
}
var Father = function(age){
  this.age = age;
} 
Father.prototype = new Person('Beijin');
console.log(Person.prototype.constructor===Person) //true
console.log(Father.prototype.constructor===Person); //true
Father.prototype.constructor = Father;//修正
console.log(Father.prototype.constructor===Father); //true
var one = new father(25);
console.log(one.constructor===Father) // true

注意這一行程式碼

Father.prototype.constructor = Father;//修正

為什麼要修正?不是說constructor是原型物件上的屬性,預設指向這個原型的建構子?
我們把這一行打碼註解掉

function Person(area){
  this.type = 'person';
  this.area = area;
}
Person.prototype.sayArea = function(){
  console.log(this.area);
}
var Father = function(age){
  this.age = age;
} 
Father.prototype = new Person('Beijin');
console.log(Person.prototype.constructor===Person) //true
console.log(Father.prototype.constructor===Person); //true
//Father.prototype.constructor = Father;//修正
console.log(Father.prototype.constructor===Father); //false
var one = new Father(25);
console.log(one.constructor===Person) // true

聰明如你,相信你已經發行了問題所在

Father.prototype = new Person('Beijin');

這一步的時候,原型指向了一個新對象,這個新物件的constructor指向的是Person。

console.log((new Person('Beijin')).__proto__ === Person.prototype) //true

前面我們說過new Person('Beijin')物件是沒有prototype的,prototype只有函數才有;Father.prototype.constructor將會沿著new Person('Beijin')的原型鏈向下查找constructor,new Person('Beijin')沒有constructor就去它的__proto__找,因為(new Person('Beijin'))._proto_ === Person.prototype而Person. prototype.constructor ==  function Person(),所以Father.prototype.constructor == Person.prototype.constructor //function Person()當我們var one = new Father(25) 時,one.constructor = Father.prototype.constructor ,所以one.constructor指向function Person(),所以,一定要修正,否則原型鏈會亂

以上是javascript建構函數的深入探討的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除