JavaScript原型对象(二)

2017-08-19  本文已影响0人  咖喱不爱吃素

原型链

原型链:对象的属性和方法,有可能是定义在自身,也有可能是定义在它的原型对象。由于原型本身也是对象,又有自己的原型,所以形成了一条原型链。

“原型链”的作用:读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就到它的原型去找,如果还是找不到,就到原型的原型去找。如果直到最顶层的Object.prototype还是找不到,则返回undefined

JavaScript中通过原型链实现了类似面向对象编程语言中的继承,我们在复制一个对象时,只用复制其自身的属性即可,无需将整个原型链进行一次复制,Object.prototype下的hasOwnProperty方法可以判断一个属性是否是该对象自身的属性。

实例对象、构造函数、prototype之间的关系可用下图表示:

原型图.jpg

constructor 属性

constructor属性定义在prototype对象上面,默认指向prototype对象所在的构造函数,可以被所有实例对象继承。

function P() {}
var p = new P();
p.constructor// function P() {}
p.constructor === P.prototype.constructor// true
p.hasOwnProperty('constructor')// false

p是构造函数P的实例对象,但是p自身没有contructor属性,该属性其实是读取原型链上面的P.prototype.constructor属性。

instanceof 运算符

instanceof运算符返回一个布尔值,表示指定对象是否为某个构造函数的实例。

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

var d = new Date();
d instanceof Date // true
d instanceof Object // true

Object.getPrototypeOf()

Object.getPrototypeOf方法返回一个对象的原型。这是获取原型对象的标准方法。

// 空对象的原型是Object.prototype
Object.getPrototypeOf({}) === Object.prototype
// true

// 函数的原型是Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype
// true

// f 为 F 的实例对象,则 f 的原型是 F.prototype
var f = new F();
Object.getPrototypeOf(f) === F.prototype
// true

获取原型对象方法的比较

如前所述,__proto__属性指向当前对象的原型对象,即构造函数的prototype属性。

var obj = new Object();

obj.__proto__ === Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true

上面代码首先新建了一个对象obj,它的__proto__属性,指向构造函数(Objectobj.constructor)的prototype属性。所以,两者比较以后,返回true。

因此,获取实例对象obj的原型对象,有三种方法。

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

上面三种方法之中,前两种都不是很可靠。最新的ES6标准规定,__proto__属性只有浏览器才需要部署,其他环境可以不部署。而obj.constructor.prototype在手动改变原型对象时,可能会失效。

var P = function () {};
var p = new P();

var C = function () {};
C.prototype = p;
var c = new C();

c.constructor.prototype === p // false

参考链接
http://www.jianshu.com/p/1160d65ce3c3
http://javascript.ruanyifeng.com/oop/prototype.html#toc3

上一篇 下一篇

猜你喜欢

热点阅读