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面向对象编程指南》