你不知道的 JavaScript 系列上( 52 ) - .constructor

function Foo(name) {
  this.name = name;
}
Foo.prototype.myName = function () {
  return this.name;
}

var a = new Foo('a');
var b = new Foo('b');

a.myName(); // 'a'
b.myName(); // 'b'

这段代码展示了“面向类”的 2 个技巧

1、this.name = name 给每个对象都添加了 .name 属性。(this 的 new 绑定规则)
2、Foo.prototype.myName 给 Foo.prototype对象添加了一个函数。a.myName 能正常工作是因为在创建的过程中,a 和 b 的内部都会关联到 Foo.prototype 上。当 a 和 b 中无法找到 myName 时,它会通过委托在 Foo.prototype 找到

 

a.constructor === Foo 为真意味着 a 确实有一个指向 Foo 的 .constructor 属性,但是事实不是这样。.constructor 引用同样被委托给了 Foo.prototype,而 Foo.prototype.constructor 默认指向 Foo

 

Foo.prototype 的 .constructor 属性只是 Foo 函数在声明时的默认属性。如果创建了一个新对象并替换了函数默认的 .prototype 对象引用,那么新对象并不会自动获得 .constructor 属性
function Foo() {/** .. */}
Foo.prototype = {/** .. */} // 创建一个新原型对象
var a1 = new Foo();
a1.constructor === Foo; // false
a1.constructor ==== Object; // true

a1 并没有 .constructor 属性,所以它会委托 [[Prototype]] 链上的 Foo.prototype。但是这个对象也没有 .constructor 属性,所以它会继续委托,这次会委托到委托链顶端的 Object.prototype。 这个对象有 .constructor 属性,指向内置的 Object(...) 函数。

当然也可以给 Foo.prototype 手动添加一个 .constructor 属性。.constructor 并不是一个不可变属性。所以 a1.constructor 实际上是不被信任的。它们不一定指向默认的函数引用。a1.constructor 是一个非常不可靠并且不安全的引用。通常来说要尽量避免使用这些引用

 

posted @ 2020-04-15 06:48  wzndkj  阅读(123)  评论(0编辑  收藏  举报