我有这样的例子。
function Bar() {
this.barVal = "BarValue";
}
function Foo() {
this.fooVal = "FooValue";
Bar.apply(this, arguments); // here I use apply() to get access everything in Bar from Foo;
}
var barObj = new Bar;
var fooObj = new Foo;
alert(fooObj.barVal); // the output is `BarValue`
现在我希望以相同的方式访问来自Bar的Foo中的所有内容。我修改了我的代码:
function Bar() {
this.barVal = "BarValue";
Foo.apply(this, arguments); // I add the same line of code, just change names
}
function Foo() {
this.fooVal = "FooValue";
Bar.apply(this, arguments); // and also leave it here because I want previous functionality too
}
var barObj = new Bar;
var fooObj = new Foo;
alert(fooObj.barVal);
alert(barObj.fooVal); // there is no any output for both
但没有任何输出。我发生了一些错误。当我在评论下隐藏Foo.apply(this, arguments);
时,通话alert(fooObj.barVal);
再次有效。当我这样检查时:
function Bar() {
this.barVal = "BarValue";
try {
Foo.apply(this, arguments);
}
catch(e) {
alert(e);
}
}
它甚至会停止浏览器工作(我使用Chrome,因此整个blaсk屏幕上出现像素文件夹)。在警报窗口中,它会写RangeError: undefined
但是因为我按此顺序进行了警报呼叫
alert(fooObj.barVal);
alert(barObj.fooVal);
第二个警报显示了我正在等待的内容 - 它显示BarValue
。
为什么apply()在Bar中复制时不起作用?有可能以某种方式在两个函数之间建立这样的门吗?
答案 0 :(得分:2)
apply
使用您指定的任何this
调用该函数。
想一想。如果Foo
拨打Bar
,Bar
拨打Foo
,那么您最终会收到无限递归。您需要某种方式来说“不要再次呼叫Foo
”。或者至少,Foo需要能够看到“嘿,我已经被召唤过一次;这次不做任何事情。”
但是,事实上,你需要做任何这些气味的事实。你通常不希望像这样的循环依赖;如果这两个东西交织在一起以至于它们需要彼此的功能才能工作,听起来你可能能够将交织在一起的东西拆分成一个单独的类型并同时使用Foo
和Bar
来自在那里,或者既有继承权,也有某种东西。但我需要看到更多的设计才能说出任何具体的设计。