我们写了很多JavaScript代码来运行我们的自动化测试,使用一个叫做TestComplete的工具。在一些情况下,我使用以下语法设置了继承树:
function Parent()
{
...
//some inline code here executes on object creation
}
Child.prototype = Parent;
Child.prototype.constructor = Child;
function Child()
{
Parent.call(this);
...
}
我使用
的原因Child.prototype = Parent;
不是Child.prototype = new Parent();
是因为在某些情况下,在父对象中创建新对象时会执行代码。以这种方式设置原型从来都不是问题,因为我总是能够在创建Child之后调用父类中定义的所有函数。
我怀疑,然而,我实际上已经打破了原型链在这样做,我已经被我们定义的所有方法都是内联定义(即。在构造函数内部)并且没有使用object.prototype.method =…语法,因此链被打破的事实被忽视了。
我有两个问题;我打破了这个链吗?在JavaScript中打破原型链的副作用是什么?
当你像这样"打破"原型链时,你不能在Child
实例中访问Parent.prototype.*
的方法和属性,并且instanceof
操作符不能工作(new Child() instanceof Parent === false
)。
我理解你为什么不想用new
关键字来继承。但是,有一个小技巧可以在继承父类原型的同时不执行父类的构造函数:
var Parent = function () { ... };
var Child = function () {
Parent.call(this);
...
};
var Fn = function () {};
Fn.prototype = Parent.prototype;
Child.prototype = new Fn();
Child.prototype.constructor = Child;
好了,这段代码将为您运行,并允许访问原型。它包括使父类成为对象字面量,你可以在子类的"构造函数"中调用原型方法
var Parent = {
testMethod1 : function() {
alert('testMethod1');
}
}
Parent.testMethod2 = function() {alert('testMethod2');}
Child.prototype = Parent;
//Child.prototype.constructor = Child;
function Child()
{
alert('im ready');
Child.prototype.testMethod1();
}
var child1 = new Child();
child1.testMethod1();
child1.testMethod2();
Parent.testMethod3 = function() {alert('testMethod3');}
child1.testMethod3();
如果你不想使用'new',你可以使用Object.create()
var Parent = {
testMethod1 : function() {
alert('testMethod1');
}
}
Parent.testMethod2 = function() {alert('testMethod2');}
var child1 = Object.create(Parent);
child1.testMethod1();
child1.testMethod2();
Parent.testMethod3 = function() {alert('testMethod3');}
child1.testMethod3();
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
在第二种情况下,你需要在创建()对象之后调用一个函数作为你的"构造函数",但这是真正的原型继承。