哪个更安全 - 使用自己还是这个?

时间:2014-02-11 03:07:31

标签: javascript closures this

使用关键字“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
        });
    } 
     

});

5 个答案:

答案 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 '来自功能之外。在我的示例中,thisself传递。

注意:您不必使用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中的模拟方式)。

遇到麻烦的地方是封闭形成后意外改变闭包中保持的变量的值。这不会发生在原始代码中。