3

我遇到了另一个开发人员的代码,它做了这样的事情来定义一个 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 的教程中的一些示例代码。有问题的实际类型不称为Ninja,并且更长更复杂。

此外,我已经阅读构造函数和原型指南并理解了,例如原型如何在属性查找中使用以及为什么 isinstanceof仍然有效。

4

1 回答 1

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
};
于 2013-11-05T05:25:17.837 回答