在學習過程中對js的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) //function person() console.log(Father.prototype.constructor); //function person() Father.prototype.constructor = Father; //修正 console.log(Father.prototype.constructor); //function father() var one = new Father(25);
Father.prototype.constructor = Father,這里修正了的Father的constructor。我們知道prototype下的constructor屬性返回對創建此對象的函數的引用。
一、不修正時
Father.constructor = function Function(),Father.prototype.constructor = function Person(),這里引出
一個題外話,為什么Father.constructor !== Father.prototype.constructor。是所有對象(包括函數)都有的,它才叫做對象的原型,原型鏈就是靠它形成的。
1. _proto_2. prototype
只有函數(准確地說是構造函數)才有的。它跟原型鏈沒有關系。它的作用是:構造函數new對象的時候,告訴構造函數新創建的對象的原型是誰。
Father.constructor,是從Father的原型鏈查找屬性,也就是__proto__
,因為Father繼承的是Function(){},而Function(){}的constructor就是它自己
所以Father.constructor = function Function();
為什么Father.prototype.constructor 是 function Person(),首先Father.prototype = new Person('Beijin');當我們用new
運算符會產生以下步驟:
- var obj={}; 也就是說,初始化一個對象obj。
- obj.__proto__=a.prototype;
- a.call(obj);也就是說構造obj,也可以稱之為初始化obj。
也就是說(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(),

二、修正時
當我們加上Father.prototype.constructor = Father;對象one的原型鏈變成

顯而易見,one.constructor = Father.prototype.constructor = function Father();
三、作用
var man; (function(){ function Father (name) { this.name = name; } Father.prototype.sayName= function () { console.log(this.name); } man = new Father('aoyo'); })() man.sayName();//aoyo console.log(Father); //Father is not defined
因為Father在閉包中,當我們想對Father類增加方法時可以通過
man.constructor.prototype.sayAge = function(age){ console.log(age); } man.sayAge('20'); //20
如果不進行修正,我們的方法將會添加到Person類,而不是Father類。