【问题标题】:Javascript object lost constructor when the prototype was changed更改原型时 Javascript 对象丢失构造函数
【发布时间】:2016-12-08 08:04:30
【问题描述】:

在下面的代码中

var A = function() {};
var a = new A();
var b = new A();

A.prototype = {};

var c = new A();
console.log(a.constructor === b.constructor);
console.log(a.constructor === c.constructor);

输出为truefalse

我对错误输出感兴趣。 ac 是使用 same 构造函数创建的,即 A - 为什么它们的构造函数属性不同?我好像错过了什么。

PS。如果我删除要更改 A 输出原型的行是:true true

【问题讨论】:

标签: javascript prototype


【解决方案1】:

当你构造一个对象时,构造函数的prototype 属性复制到新对象的__proto__,所以ab 保留旧原型(其中还包含.constructor 属性),c 使用新的空白原型(没有 constructor 作为自己的属性)。这是一个图表:

a = new A; b = new A之后:

A.prototype = {}; c = new A()之后

如您所见,直接分配给原型会破坏 JS 对象系统,并可能导致令人惊讶的结果(您的问题就证明了这一点)。这就是为什么它通常不受欢迎的原因。

【讨论】:

  • 我很想知道你用什么软件来创建那个图表!
  • 为什么改变函数原型会影响对象的构造函数属性?
  • @GiorgiMoniava:对象没有内在的constructor 属性,它属于原型。
【解决方案2】:

问题在于,当您使用A.prototype={} 时,A 对象的行为会发生变化。

当你使用A.prototype={}时,一个对象丢失了它是constructor

为什么会出现这种行为?

constructor 属性分配给prototype 函数。

在您的情况下,A.prototype 被替换为新对象 {},它没有 constructor 属性作为自己的属性(但它的原型具有并且等于 Object)。

让我们看看下面的例子:

function A() { } // (1)
A.prototype = {}  // (2)

在(2)之前

Object.prototype
{
    constructor:Object
}

A.prototype
//was autocreated with A
{
    constructor:A
}

在 (2) 之后

Object.prototype
{
    constructor:Object
}

A.prototype
//reassigned with {}
{
   //no constructor
}

【讨论】:

    【解决方案3】:

    当使用函数作为对象构造函数时,它的prototype.constructor 会自动使用函数的属性创建。所以最初在设置 A 函数后,你将在 A 的原型中拥有一个构造函数:

    A.prototype.constructor
    

    因此,当您分配 A.prototype ={} 时,您丢失了 A.prototype 中的原始构造函数。

    您可以在A.prototype ={} 行之后添加它来修复它

    A.prototype.constructor = A;
    

    两个控制台都应该记录为真

    【讨论】:

      猜你喜欢
      • 2015-03-16
      • 2013-05-25
      • 2012-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 2010-10-07
      • 1970-01-01
      相关资源
      最近更新 更多