原型与原型链知识梳理

总结

prototype

  1. 原型的理解:每个函数对象都有原型对象,构造函数生成实例时,该属性会称为实例对象的原型,原型对象用来定义所有实例共享的属性的方法。
  2. 原型链的理解:每个对象都有 __proto__ 属性,指向其构造函数的原型对象。构造函数的原型对象也是对象,也有自己的 __proto__ 属性,由此形成原型链。对象方法查找时,在本身找不到时,向原型链上找。

js 继承机制的设计思想是,原型对象的所有属性和方法,都能被实例对象共享。 也就是说,如果属性和方法定义在原型上,那么所有实例对象都能共享,不仅节省了内存,还体现了实例对象之间的联系。

函数 prototype 属性的作用

js 规定,每个函数都有一个 prototype 属性,指向一个对象。

function f() {}
typeof f.prototype // "object"
  • 对于普通函数来说,该属性基本无用。但是,对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型。
  • 原型对象的属性不是实例对象自身的属性。只要修改原型对象,变动就立刻会体现在所有实例对象上。
  • 如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。

总结一下,原型对象的作用,就是定义所有实例对象共享的属性和方法。 这也是它被称为原型对象的原因,而实例对象可以视作从原型对象衍生出来的子对象。

prototype 的验证方法

isPrototypeOf()

对象方法,判断某个 prototype 对象和某个实例之间的关系。

alert(Cat.prototype.isPrototypeOf(cat1)); //true

hasOwnProperty()

对象方法,判断某一个属性是本地属性还是继承自 prototype 的属性。

alert(cat1.hasOwnProperty("name")); // true

in 操作符

判断某个实例是否含有某个属性,不管是不是本地属性。

alert("name" in cat1); // true

in 运算符还可以用来遍历某个对象的所有属性。

获得原型对象的方法

  • obj.__proto__
  • obj.constructor.prototype
  • Object.getPrototypeOf(obj)

前两种都不是很可靠。__proto__ 属性只有浏览器才需要部署,其他环境可以不部署。而 obj.constructor.prototype 在手动改变原型对象时,可能会失效。推荐第三种。

原型链

JavaScript 规定,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”(prototype chain):对象到原型,再到原型的原型……

如果一层层地上溯,所有对象的原型最终都可以上溯到 Object.prototype,即 Object 构造函数的 prototype 属性。也就是说,所有对象都继承了 Object.prototype 的属性。这就是所有对象都有 valueOftoString 方法的原因,因为这是从 Object.prototype 继承的。Object.prototype 的原型是 null。null 没有任何属性和方法,也没有自己的原型。因此,原型链的尽头就是 null

constructor 属性

prototype 对象有一个 constructor 属性,默认指向 prototype 对象所在的构造函数。

constructor 属性的作用是,可以得知某个实例对象,到底是哪一个构造函数产生的。(通过 name 属性,从实例得到构造函数的名称。)另一方面,有了 constructor 属性,就可以从一个实例对象新建另一个实例。(箭头函数没有 constructor)

修改原型对象时,一般要同时修改 constructor 属性的指向。

instanceof 运算符

instanceof 运算符的左边是实例对象,右边是构造函数。它会检查右边构建函数的原型对象(prototype),是否在左边对象的原型链上。

特殊情况:有一种特殊情况,就是左边对象的原型链上,只有 null 对象。这时,instanceof 判断会失真。
对于 undefined 和 null,instanceOf 运算符总是返回 false。

Function instanceof Object;//true
Function.__proto__ == Function.prototype;
Function.prototype.__proto == Object.prototype;

Object instanceof Function;//true
Object.__proto__ = Function.prototype;

继承

单继承

用组合继承的方法或 extend

多继承

// 继承 M1
S.prototype = Object.create(M1.prototype);
// 继承链上加入 M2
Object.assign(S.prototype, M2.prototype);
// 指定构造函数
S.prototype.constructor = S;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值