原型与原型链

sync github

原型属性 prototype

在函数被定义时创建,初始值是一个"空"对象(没有自身属性的对象)。

为新建对象添加方法和属性的方式

  1. 利用原型

// 1 构造器中
function Gadget(name, color) {
    this.name = name;
}

// 2 原型属性
Gadget.prototype.price = 66;

几个相关方法和属性

  • hasOwnProperty() 判断一个属性是自身属性还是原型属性。

通常,在for infor of 中,需要使用 hasOwnProperty()~

  • propertyIsEnumerable() 该方法会对所有的非内建对象属性返回 true

const newtoy = new Gadget('webcam');

// 对于内建属性和方法来说,不可枚举
newtoy.propertyIsEnumerable('constructor'); // false

// 任何来自原型链中的属性都会返回false,包括那些在`for-in`循环中可枚举的属性
newtoy.propertyIsEnumerable('price');   // false

// notice
newtoy.constructor.prototype.propertyIsEnumerable('price'); // true
  • isPrototypeOf() 判断当前对象是否是另一个对象的原型

  • Object.getPrototypeOf() ES5适用。获取对象的原型。效果同 特殊属性 __proto__

  • __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 属性。

Summary

来自知乎的一张图,很清晰
原型与原型链_第1张图片

Reference

  • 《JavaScript面向对象编程指南》

  • Javascript的原型链图 - wang z

你可能感兴趣的:(javascript,frontend)