原型和原型链

Prototype属性的作用

JavaScript规定所有对象都有自己的原型对象prototype。一方面任何一个对象都可以充当其他对象的原型。另一方面它也有自己的原型。所有对象最终都会上溯到Object.prototype。所有属性都继承自Object.prototype,因此,所有对象都有valueOf和toString方法。Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此原型链的最后一层是null。
···
function Animal(name){

    this.name = name;

}

Animal.prototype.color = 'black';

var cat = new Animal('cat');

var dog = new Animal('dog');

cat.color;//black

dog.color;//black

Animal.prototype.color = 'red';

cat.color;//red

cat.color = 'white';

cat.color;//white

···
原型对象的属性不是实例对象的自身属性,只要修改原型对象,马上就能作用到实例对象上。由于实例对象没有color属性,都是读取原型对象的color属性。当实例对象没有某个属性或方法时,就会去原型对象上找。如果实例对象自身拥有这个属性,则使用自身属性,不用去原型对象寻找。

原型链

JavaScript规定所有对象都有自己的原型对象prototype。一方面任何一个对象都可以充当其他对象的原型。另一方面它也有自己的原型。所有对象最终都会上溯到Object.prototype。所有属性都继承自Object.prototype,因此,所有对象都有valueOf和toString方法。Object.prototype的原型是null。null没有任何属性和方法,也没有自己的原型。因此原型链的最后一层是null。

 var obj = new 构造函数();

    obj.__proto__ === 构造函数.prototype

    var number = new Number()

    number.__proto__ = Number.prototype

    Number.__proto__ = Function.prototype // 因为 Number 是     Function 的实例

    var object = new Object()

    object.__proto__ = Object.prototype

    Object.__proto__ = Function.prototype // 因为 Object 是 Function 的实例

    var function = new Function()

    function.__proto__ = Function.prototype

    Function.__proto__ == Function.prototye // 因为 Function 是 Function 的实例!

我们首先创建一个object


let obj = {name:'obj1'}

原型和原型链_第1张图片
image

我们可以看到obj被创建后它的prototype就是Object,我们没有对obj操作,它就有了valueOf,toString等方法。

原型和原型链_第2张图片
image

它们的关系大概如下图所示:

原型和原型链_第3张图片
image

我们发现:

obj原本有个名字叫name,由我们命名。

obj有个proto属性

obj.proto有toString,constructor, valueOf等方法或属性。

这一切都和proto有关。
当我们访问obj.toString, js引擎会去检查对象本身有没有这个属性,如果没有,就去查看obj.proto有没有这个属性。

原型和原型链_第4张图片
image.png

此时已经找到toString属性。如果还是没有就会去查找obj.proto.proto 直到找到或者结果为null为止。

共享原型链

我们继续创建一个对象obj2

原型和原型链_第5张图片
image.png

此时 obj和obj2 的toString是同一个东西。如果我们改变obj. proto.toString(),此时obj2. proto的toString()也会改变。

obj.__proto__.toString = ()=> { console.log('__proto__.toString')}
原型和原型链_第6张图片
image.png

此时 obj2.proto.toString也发生了改变。这样obj和obj2就是拥有了相似行为的对象。

差异化

如果我们想让obj和obj2的toString不同,我们直接给obj2.toString赋值即可

  obj2.toString = () => { console.log('obj2') }
image.png

此时 obj2.toString发生了改变。

你可能感兴趣的:(原型和原型链)