为什么不可能从原型更改构造函数?

绿色 :

我有这样的例子。

function Rabbit() {
    var jumps = "yes";
};
var rabbit = new Rabbit();
alert(rabbit.jumps);                    // undefined
alert(Rabbit.prototype.constructor);    // outputs exactly the code of the function Rabbit();

我想更改代码,Rabbit()以使其var jumps公开。我这样做:

Rabbit.prototype.constructor = function Rabbit() {
    this.jumps = "no";
};
alert(Rabbit.prototype.constructor);    // again outputs the code of function Rabbit() and with new this.jumps = "no";
var rabbit2 = new Rabbit();             // create new object with new constructor
alert(rabbit2.jumps);                   // but still outputs undefined

为什么无法以这种方式更改构造函数中的代码?

胡安·门德斯:

您不能通过重新分配给来更改构造函数 prototype.constructor

发生的事情是Rabbit.prototype.constructor指向原始构造函数(function Rabbit(){...}的指针,因此“类”的用户可以从实例中检测到构造函数。因此,当您尝试执行以下操作时:

Rabbit.prototype.constructor = function Rabbit() {
    this.jumps = "no";
};

您只会影响依赖于prototype.constructor从实例动态实例化对象的代码

调用时new X,JS引擎不引用X.prototype.constructor,而是将X用作构造函数和X.prototype新创建的对象的原型,而忽略X.prototype.constructor

解释此问题的一个好方法是自己实施new操作员。(克罗克福德会很高兴,不再有新事物了;)

// `new` emulator
// 
// Doesn't reference `.constructor` to show that prototype.constructor is not used
// when istantiating objects a la `new`
function make(ctorFun, argsArray) {
  // New instance attached to the prototype but the constructor
  // hasn't been called on it.
  const newInstance = Object.create(ctorFun.prototype);
  ctorFun.apply(newInstance, argsArray);
  return newInstance;
}

// If you create a utility function to create from instance, then it uses the
// inherited `constructor` property and your change would affect that.
function makeFromInstance(instance, argsArray) {
  return make(instance.constructor, argsArray);
}

function X(jumps) {
  this.jumps = jumps;
}

// Flip the constructor, see what it affects
X.prototype.constructor = function(jumps) {
  this.jumps = !jumps;
}

const xFromConstructorIsGood = make(X, [true]);
const xFromInstanceIsBad = makeFromInstance(xFromConstructorIsGood, [true]);

console.log({
  xFromConstructorIsGood,
  xFromInstanceIsBad
});

JS中的继承

帮助JS继承的库实现继承并确实依赖于prototype.constructor以下内容:

function extend(base, sub) {

  function surrogateCtor() {}
  // Copy the prototype from the base to setup inheritance
  surrogateCtor.prototype = base.prototype;
  sub.prototype = new surrogateCtor();
  // The constructor property is set to the base constructor
  // with the above trick, let's fix it
  sub.prototype.constructor = sub;
}

您可以在上面的代码中看到,我们必须修复构造函数属性,因为当您只有一个实例时,有时会使用它来创建实例化对象。但这不会影响实际的构造函数。请参阅我关于JS继承的文章http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

如何重新定义构造函数如果您确实要重新定义构造函数,请执行

// If Rabbit had any custom properties on it 
// (or static properties as some call it), they would not be copied, you'd have to do that manually using getOwnPropertyNames

// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames
var oldProto = Rabbit.prototype;
Rabbit = function() {...};
Rabbit.prototype = oldProto;

请注意,这不会影响已经复制该引用的代码,例如:

const myRefRabbit = Rabbit

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么不可能显式地默认具有volatile参数的副本构造函数?

来自分类Dev

为什么不可能在特征中定义此构造函数?

来自分类Dev

为什么不可能从Objective-C目标文件中隐藏符号?

来自分类Dev

为什么不可能构建可以确定C ++函数是否会更改特定变量的值的编译器?

来自分类Javascript

为什么需要设置原型构造函数?

来自分类Dev

为什么我们不能更改内置函数构造函数的原型?

来自分类Dev

为什么包含不可能的条件分支会更改此方法的返回值?

来自分类Dev

为什么在Kotlin中不可能使用对`suspend`函数的方法引用?

来自分类Dev

如果更改了构造函数的原型,为什么对象的构造函数属性也会发生变化?

来自分类Dev

Nullable <int?>是不可能的,为什么不能呢?

来自分类Dev

为什么在C中不可能重载?

来自分类Dev

为什么在Haskell中不可能分割整数?

来自分类Dev

为什么阶乘1000年不可能的BigInteger?

来自分类Dev

volatile struct = struct不可能,为什么?

来自分类Dev

为什么本文中的这个问题是不可能的?

来自分类Dev

为什么不可能用焦点影响子元素?

来自分类Dev

为什么原型的构造函数会引用回自身?

来自分类Dev

为什么在原型而不是构造函数中声明实例属性?

来自分类Dev

在构造函数内部*分配原型方法-为什么不呢?

来自分类Java

为什么不能从枚举构造函数调用超级构造函数?

来自分类Dev

不可能从 AWS Lambda 连接到 RDS MySQL

来自分类Dev

不可能从猫鼬对象获得财产

来自分类Dev

为什么在给出预购,后购和级别订单遍历的情况下构造二叉树是不可能的?

来自分类Dev

不可能更改gitlab项目网址

来自分类Dev

为什么我得到“候选构造函数不可行”?

来自分类Dev

新的JavaScript原型更改了构造函数

来自分类Dev

SHARE锁定记录的行为,为什么聚合功能不可能?

来自分类Dev

为什么 Collection.equals() JavaDoc 说不可能正确实现 List 和 Set?

来自分类Dev

为什么在Scala中不可能将变量与`to`一起使用?

Related 相关文章

  1. 1

    为什么不可能显式地默认具有volatile参数的副本构造函数?

  2. 2

    为什么不可能在特征中定义此构造函数?

  3. 3

    为什么不可能从Objective-C目标文件中隐藏符号?

  4. 4

    为什么不可能构建可以确定C ++函数是否会更改特定变量的值的编译器?

  5. 5

    为什么需要设置原型构造函数?

  6. 6

    为什么我们不能更改内置函数构造函数的原型?

  7. 7

    为什么包含不可能的条件分支会更改此方法的返回值?

  8. 8

    为什么在Kotlin中不可能使用对`suspend`函数的方法引用?

  9. 9

    如果更改了构造函数的原型,为什么对象的构造函数属性也会发生变化?

  10. 10

    Nullable <int?>是不可能的,为什么不能呢?

  11. 11

    为什么在C中不可能重载?

  12. 12

    为什么在Haskell中不可能分割整数?

  13. 13

    为什么阶乘1000年不可能的BigInteger?

  14. 14

    volatile struct = struct不可能,为什么?

  15. 15

    为什么本文中的这个问题是不可能的?

  16. 16

    为什么不可能用焦点影响子元素?

  17. 17

    为什么原型的构造函数会引用回自身?

  18. 18

    为什么在原型而不是构造函数中声明实例属性?

  19. 19

    在构造函数内部*分配原型方法-为什么不呢?

  20. 20

    为什么不能从枚举构造函数调用超级构造函数?

  21. 21

    不可能从 AWS Lambda 连接到 RDS MySQL

  22. 22

    不可能从猫鼬对象获得财产

  23. 23

    为什么在给出预购,后购和级别订单遍历的情况下构造二叉树是不可能的?

  24. 24

    不可能更改gitlab项目网址

  25. 25

    为什么我得到“候选构造函数不可行”?

  26. 26

    新的JavaScript原型更改了构造函数

  27. 27

    SHARE锁定记录的行为,为什么聚合功能不可能?

  28. 28

    为什么 Collection.equals() JavaDoc 说不可能正确实现 List 和 Set?

  29. 29

    为什么在Scala中不可能将变量与`to`一起使用?

热门标签

归档