使用关键字“this”创建新的Locker是否安全?我担心“this”可能会指向运行时的其他内容。 我是JavaScript和闭包的新手。
var Employee = function() { this.initialize.apply(this, arguments); }; _.extend(Employee.prototype, { initialize : function(opts) { this._locker = new Locker({ employee : this }); // OR var self = this; this._locker = new Locker({ employee : self }); }
});
答案 0 :(得分:2)
特别关注此代码:
this._locker = new Locker({
employee : this
});
假设this
已指向正确的对象,则上述内容不会引入新范围;它与写作相同:
var options = {
employee : this
};
this._locker = new Locker(options);
答案 1 :(得分:1)
在这种情况下,您无需使用self
。
当有人希望将self
的值传递到不同的范围作为闭包时,您会看到this
。
var self = this;
var myFunc = function() {
// do something with self (aka this)
};
在上面的示例中,this
内的myFunc
在调用函数之前不会被人知道 - 谷歌'动态与静态作用域' - 它不会是'this
'来自功能之外。在我的示例中,this
以self
传递。
注意:您不必使用self
任何其他变量名称。
在您的示例中,您并未尝试将this
传递到其他范围,因此应该没问题。
答案 2 :(得分:1)
两个片段的行为相同。
this
的值由如何调用函数确定,因此你是正确的this
可能在运行时指向其他东西。
但是,一旦调用了initialize
,就已经设置了该调用的this
值。所以:
var self = this;
this._locker = new Locker({
employee : self
});
只需添加一个中间步骤,将this
分配给临时变量(请参阅Jack的)答案
答案 3 :(得分:0)
你更安全的赌注是使用“this”,因为你正在使用apply并传递“this”。 Apply将强制“this”关键字成为您传递给函数的thisArg。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
“self”在初始化的早期设置为Window对象,但我认为它不会改变,除非你专门更改它。
答案 4 :(得分:0)
使用关键字“this”创建新的Locker是否安全?
是
> var Employee = function() {
> this.initialize.apply(this, arguments);
> };
在使用 new 调用的函数中(即称为构造函数),此将始终指向新实例。使用 apply 意味着 arguments 不作为Object传递,而是作为一系列值传递。所以我认为你应该这样做:
function Employee () {
this.initialize(arguments);
}
请注意,函数声明比函数表达式更少代码且更可靠。
> _.extend(Employee.prototype, {
> initialize : function(opts) {
由于您使用 apply 并使用 arguments 作为参数对象来调用它,因此参数将按值单独传递。所以 opts 将是最初传递给 Employee 构造函数的参数的第一个值,其他值将作为此新函数的参数的成员提供对象
>
> this._locker = new Locker({
> employee : this
> });
> }
在调用函数时(或通过 bind )设置 this 的值。在这种情况下, initialize 旨在作为实例的方法调用,因此 this 将引用该实例。它可以通过其他方式调用,因此此引用其他对象(或者在严格模式下为任何值),但以下内容对此没有影响。
此代码对传递给 Locker 的值没有任何影响:
> var self = this;
> this._locker = new Locker({
> employee : self
> });
你似乎试图避免关闭,但这里没有关闭以避免。闭包不是由函数调用引起的,而是由函数返回在其中创建的其他函数(通过声明或表达式)引起的。这些函数在完成后继续可以访问外部函数的词法环境,例如
var foo = (function() {
var bar = 'bar';
return function(){ return bar;};
}());
foo(); // bar
函数 foo 具有对外部函数中声明的变量 bar 的闭包。没有其他功能可以访问 bar 来读取或设置其值,它只适用于 foo (这是私有成员在javascript中的模拟方式)。
遇到麻烦的地方是封闭形成后意外改变闭包中保持的变量的值。这不会发生在原始代码中。