我们说我有这个代码
(function() {
function Foo(arg) {
this.name = arg;
}
Foo.prototype = {
bar: {
baz: function() {
alert(this.name); // Undefined...
}
}
}
var foo = function(arg) {
return new Foo(arg);
};
window.foo = foo;
return foo;
}());
foo("Anything").bar.baz();
我如何制作"这个"在我的功能" baz"当我从外面调用它时,是指对象Foo而不使用bind或apply?
答案 0 :(得分:2)
FWIW,我强烈建议不构建这样的嵌套结构,或至少不在原型上,因为bar
对象共享这些实例打开了通向交谈式错误的很多的大门。相反,我在构造函数中创建bar
。
我如何制作"这个"在我的功能" baz"当我从外面调用它时,是指对象Foo而不使用bind或apply?
您可能会对bind
和apply
/ call
稍有疑惑。当调用函数时,你不会使用bind
,但在创建它时。除非您使用bind
(或与其相同的内容),否则您无法执行您想要的内容,因为缺少bind
(或类似),this
是根据函数的调用方式设置的,因此this.bar.baz()
会使this
成为调用中的this.bar
。
以下是如何在构造函数中构建bar
,并使用bind
使baz
使用正确的this
:
function Foo(arg) {
this.name = arg;
this.bar = {
baz: function() {
alert(this.name);
}.bind(this) // <== Note
};
}
示例:
function Foo(arg) {
this.name = arg;
this.bar = {
baz: function() {
snippet.log(this.name);
}.bind(this) // <== Note
};
}
var f1 = new Foo("f1");
var f2 = new Foo("f2");
f1.bar.baz(); // "f1"
f2.bar.baz(); // "f2"
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
有关串扰的更多信息:天真的事情是只需在Foo
构造函数中添加一行,并在原型上保留bar
:
this.bar.baz = this.bar.baz.bind(this);
这将是一个非常糟糕的主意,因为您会在实例之间进行串扰:
function Foo(arg) {
this.name = arg;
this.bar.baz = this.bar.baz.bind(this); // DON'T DO THIS
}
Foo.prototype = {
bar: {
baz: function() {
snippet.log(this.name);
}
}
};
var f1 = new Foo("f1");
var f2 = new Foo("f2");
f2.bar.baz(); // "f1" -- cross talk! Should be f2
&#13;
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
答案 1 :(得分:0)
在声明时使用bind来正确地确定范围,例如
function foo() {}.bind(this);