替换Javascript构造函数的.prototype而不是添加它有问题吗?

时间:2013-11-05 05:15:25

标签: javascript constructor prototype prototype-programming

我遇到了另一个开发人员的代码,它执行类似这样的操作来定义Javascript类型:

function Ninja() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  }
}

当更传统的方式是这样的时候:

function Ninja() {}
Ninja.prototype.swingSword = function() {
    return true;
}

第一种形式大多有效,因为你可以创建一个新实例并调用swingSword  方法,instanceof准确无误:

var ninja = new Ninja();
ninja.swingSword(); // returns true
ninja instanceof Ninja; // also true

但是,ninja.constructor指向Object而非Ninja功能。这对我来说是一个问题:我正在尝试通过实例访问构造函数,作为构造函数的解决方法,不以任何其他方式公开。但是,除了访问反射/变通方法黑客的constructor属性之外,第一种形式是否会导致任何重大问题?

原始Ninja.prototype的其他重要属性是否可能被隐藏?第一种形式会导致继承类型或公共库的任何问题吗?

我正在试图弄清楚这是一个不寻常但可以接受的Javascript模式,或者实际上是一个常见的Javascript失误或“陷阱”,应该被认为是一个错误。

请注意,我的Ninja示例基于John Resig教程中的一些example code。有问题的实际类型不称为Ninja,而且更长,更复杂。

此外,我已阅读构建器和原型的this指南,并了解,例如,如何在属性查找中使用原型,为什么 isinstanceof仍然有效。

1 个答案:

答案 0 :(得分:3)

当您从另一个原型“继承”时,通常会替换整个原型,如果构造函数很重要,您可以将其设置为“正确”值:

var Child = function(){};
//"inherit" from Parent
Child.prototype=Object.create(Parent.prototype);
//reset the constructor
Child.prototype.constructor = Child;

因此,在您的情况下,只需在设置原型后修复构造函数:

var Ninja = function() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  }
};
// you can put the next line anywhere you want to fix the problem
// http://stackoverflow.com/a/16063711/1641941 under this.constructor
Ninja.prototype.constructor=Ninja;

或者:

var Ninja = function() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  },
  constructor:Ninja
};