1.Object2.Function3.Array4.Date5.String
下面我們來舉一些例子吧
//每個function都有一個默認的屬性prototype,而這個prototype的constructor默認指向這個函數 //注意Person.constructor 不等於 Person.prototype.constructor. Function實例自帶constructor屬性 function Person(name) { this.name = name; }; Person.prototype.getName = function() { return this.name; }; var p = new Person("ZhangSan"); console.log(Person.prototype.constructor === Person); // true console.log(p.constructor === Person); // true ,這是因為p本身不包含constructor屬性,所以這里其實調用的是Person.prototype.constructor
1.表明Person繼承自Animal2. 表明p2是Person的實例
function Person(name) { this.name = name; }; Person.prototype.getName = function() { return this.name; }; var p1 = new Person("ZhangSan"); console.log(p.constructor === Person); // true console.log(Person.prototype.constructor === Person); // true function Animal(){ } Person.prototype = new Animal();//之所以不采用Person.prototype = Animal.prototype,是因為new 還有其他功能,最后總結。 var p2 = new Person("ZhangSan"); //(p2 -> Person.prototype -> Animal.prototype, 所以p2.constructor其實就是Animal.prototype.constructor) console.log(p2.constructor === Person); // 輸出為false ,但我們的本意是要這里為true的,表明p2是Person的實例。此時目的1達到了,目的2沒達到。
Person.prototype = new Animal();Person.prototype.constructor = Person;
1表示父類是誰2作為自己實例的原型來復制
Person.prototype = new Animal(); Person.prototype.constructor = Person; var p2 = new Person("ZhangSan"); p2.constructor //顯示 function Person() {} Object.getPrototypeOf(Person.prototype).constructor //顯示 function Animal() {}
當代碼var p = new Person()執行時,new 做了如下幾件事情:
創建一個空白對象
創建一個指向Person.prototype的指針
將這個對象通過this關鍵字傳遞到構造函數中並執行構造函數。
具體點來說,在下面這段代碼中,
Person.prototype.getName = function() { }
如果我們通過
var person = new Person(); 其實類似於 var person = new Object(); person.getName = Person.prototype.getName;
因此通過person.getName()調用方法時,this指向的是這個新創建的對象,而不是prototype對象。
這其實在給現有函數加上新功能的情況下會用到,我們可以這么擴展現有的方法:
//function myFunc 的寫法基本上等於 var myFunc = new Function(); function myFunc () { } myFunc = function(func){
//可以在這里做點其他事情 return function(){
//可以在這里做點其他事情 return func.apply(this,arguments); } }(myFunc)
也可以在Function.prototype方法里直接通過this來訪問上面代碼的myFunc所指向的對象
function myFunc () { }
if (!Function.prototype.extend) { Function.prototype.extend = function(){ var func = this; return function(){ func.apply(this,arguments); } } }; var myFunc = myFunc.extend();
最后總結一下:
如果采用Person.prototype = Animal.prototype來表示Person繼承自Animal, instanceof方法也同樣會顯示p也是Animal的實例,返回為true.
之所以不采用此方法,是因為下面兩個原因:
1.new 創建了一個新對象,這樣就避免了設置Person.prototype.constructor = Person 的時候也會導致Animal.prototype.constructor的值變為Person,而是動態給這個新創建的對象一個constructor實例屬性。這樣實例上的屬性constructor就覆蓋了Animal.prototype.constructor,這樣Person.prototype.constructor和Animal.prototype.contructor就分開了。
2.Animal自身的this對象的屬性沒辦法傳遞給Person
但是像下面這樣直接調用構造函數又可能失敗,或者產生其他影響。
Person.prototype = new Animal();
為了避免這種情況,所以我們引入了一個中間函數。所以正確的做法應該是
Person.prototype = (funtion(){ function F(){}; F.prototype = Animal.prototype return new F(); })()