一张图让你理清javascript中__proto__, prototype, 以及constructor之间的关系

如下图所示

画的有点不太好看, 但是关系还是很清楚的

这里写图片描述

此处有一点需要注意: Foo.prototype默认有一个公有并且不可枚举的属性.constructor, 这个属性引用的是对象关联的函数. 例如上图的例子f1 = new Foo(), 虽然f1.constructor确实指向Foo函数, 但是这个属性并不是表示f1Foo“构造”.

看起来f1.constructor === Foo为真意味着f1确实有一个指向Foo.constructor属性, 但事实不是这样.

这是一个很不幸的误解. 实际上, .constructor引用同样被委托给了Foo.prototype, 而Foo.prototype.constructor默认指向Foo.

.constructor属性指向Foo看作是f1对象由Foo构造非常容易理解, 但这只不过是一种虚假的安全感. f1.constructor只是通过默认的[[Prototype]]委托指向Foo, 这和构造毫无关系, 相反, 对于.constructor的错误理解很容易对你自己产生误导.

举例来说, Foo.prototype.constructor属性只是Foo函数在声明时的默认属性. 如果你创建了一个新对象并替换了函数默认的.prototype对象引用, 那么新对象并不会自动获得.constructor属性.

那么我们怎么判断原型呢

1. ES3 isPrototypeOf()

isPrototypeOf() 方法用于测试一个对象是否存在于另一个对象的原型链上。

// 例子
function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true bar是baz的原型吗? 是就返回true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true

2. ES5 Object.getPrototypeOf()

Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)

// 例
var proto = {};
var obj = Object.create(proto);
Object.getPrototypeOf(obj) === proto; // true

var reg = /a/;
Object.getPrototypeOf(reg) === RegExp.prototype; // true

// 这里再注意一下
Object.getPrototypeOf(Object) === Function.prototype;        // true

3. ES6 __proto__

ES6规范更加直接,为对象添加了一个__proto__属性,通过这个属性就可以获得对象的原型,所以在支持__proto__的浏览器中,o.__proto__ === Object.prototype也会返回true。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值