sync githubgit
在函數被定義時建立,初始值是一個"空"對象(沒有自身屬性的對象)。github
爲新建對象添加方法和屬性的方式web
利用原型編程
// 1 構造器中 function Gadget(name, color) { this.name = name; } // 2 原型屬性 Gadget.prototype.price = 66;
hasOwnProperty()
判斷一個屬性是自身屬性仍是原型屬性。函數
一般,在
for in
和for of
中,須要使用hasOwnProperty()
~this
propertyIsEnumerable()
該方法會對全部的非內建對象屬性返回 truespa
const newtoy = new Gadget('webcam'); // 對於內建屬性和方法來講,不可枚舉 newtoy.propertyIsEnumerable('constructor'); // false // 任何來自原型鏈中的屬性都會返回false,包括那些在`for-in`循環中可枚舉的屬性 newtoy.propertyIsEnumerable('price'); // false // notice newtoy.constructor.prototype.propertyIsEnumerable('price'); // true
isPrototypeOf()
判斷當前對象是不是另外一個對象的原型prototype
Object.getPrototypeOf()
ES5適用。獲取對象的原型。效果同 特殊屬性 __proto__
code
__proto__
對象
notice: 不要在實際的腳本中使用。另,
__proto__
與prototype
的區別,__proto__
其實是某個實例對象的屬性,而prototype
則屬於構造器函數的屬性。
當咱們對原型對象執行徹底替換時,可能會觸發原型鏈中某種異常
prototype.constructor
屬性是不可靠的
體會下面的輸出內容
function Dog() { this.tail = true; } var benji = new Dog(); var rusty = new Dog(); Dog.prototype.say = function() { return 'Woof!'; }; benji.say(); // 'Woof!' rusty.say(); // 'Woof!' benji.constructor === Dog; // true rusty.constructor === Dog; // true // 用一個自定義的新對象徹底覆蓋掉原有的原型對象 Dog.prototype = { paws: 4, hair: true, }; // 發現經過構造函數建立的對象 prototype 對象並無改變 typeof benji.paws; // undefined benji.say(); // Woof typeof benji.__proto__.say; // function typeof benji.__proto__.paws; // undefined // 經過構造函數建立的對象使用新的 prototype 對象 var lucy = new Dog(); lucy.say(); // TypeError: lucy.say is not a function lucy.paws; // 4 typeof lucy.__proto__.say; // undefined typeof lucy.__proto__.paws; // number //可是!!!注意此時新對象的 constructor 屬性的指向 lucy.constructor; // function Object(){[native code]} benji.constructor; // function Dog() {...} // solve Dog.prototype.constructor = Dog; new Dog().constructor === Dog; // true lucy.constructor; // function Dog() {...}
當咱們重寫某對象的
prototype
時, 須要重置相應的constructor
屬性。
來自知乎的一張圖,很清晰
《JavaScript面向對象編程指南》