为什么要创建一个具有此值的变量

时间:2012-05-30 15:07:28

标签: javascript this

我已经在JavaScript中看到了很多,我确实记得找出原因,但我记不起答案。

我猜这是与范围和在“类”之外调用的函数有关,但为什么会这样做(最好概述一个例子):

function myClass ()
{
    var self = this;

    //...

    this.myArray = [];

    this.myFunc = function () { alert(self.myArray.length); };
}

5 个答案:

答案 0 :(得分:5)

为了将变量锁定为closure的一部分。

例如:

MyClass.prototype.doStuff = function(){
  this.foundItems = [];
  var self = this;
  this.myString.replace(/.../,function(){
    // `this` is actually the `window` inside this callback
    // so we need to use `self` to invoke another method on our instance object
    self.foundItems.push( self.doOtherStuff() );
  });
};

如果以预期的方式调用方法,那么您编写的特定示例不需要闭包:

function Foo(){
  this.array = [];
  this.myFunc = function(){
    return this.array;
  }
}
var foo = new Foo;
foo.myFunc(); // []

但是,它可以像这样“打破”它:

var f2 = foo.myFunc;
f2(); // undefined, since `this` was the window

另一方面,使用闭包的代码可以安全地防止这种愚蠢行为。

答案 1 :(得分:2)

“this”指的是当前的“对象”。 在谈论javascript时,权力存在于“this”表达式是在上下文中进行评估的事实,因此,例如,如果在另一个对象上下文中执行方法,则“this”值将分别改变。

答案 2 :(得分:1)

如果在另一个函数中创建函数,则内部函数的this将设置为全局窗口对象。如果您创建一个保存this值的变量,例如

var that = this;

然后你可以使用that来引用内部函数中的外部函数。

答案 3 :(得分:0)

除了其他用户发布的一些答案之外,创建设置为此的变量允许您在不访问对象的情况下重用变量。

类似于:

var myElement = document.getElementById('someElement');

然后,如果您需要多次使用document.getElementById而不是多次访问myElement。

设置that = this或self =这使您可以访问“that”或“self”的所有位置,并防止重新加载某些对象。

答案 4 :(得分:0)

我认为没有人真的愿意这样做:

  • 每次创建实例时,您还可以创建该功能的“副本”。所以5个实例,将创建5个“副本”的功能。
  • 函数的“复制”绑定到仅与该特定实例相关的环境,因此不能一般地使用它。这意味着扩展类将获得一个方法,该方法仅与可能甚至不使用的父类的某个实例相关。
  • 如果您开始嵌套这些内联函数,您的缩进将会失控
  • 您必须在其他功能中寻找功能,而不是仅仅在原型定义中查找

替代方案:

function MyClass() {
    this.myArray = [];
    this.myFunc = this.myFunc.bind(this); //The "blueprint" in the prototype is not affected, the instance gets its own bound version.
                                           //This means the one in prototype can be inherited or used generically anywhere else as well
}

MyClass.prototype = {

    myFunc: function() { //My func is neatly listed in the prototype and can use `this` normally
        alert(this.myArray.length);
    },

    constructor: MyClass
};


var myObj = new MyClass();

document.addEventListener( "click", myObj.myFunc ); //Will now work as you "expect" it to work

一些缺点:

  • 每个绑定函数都是一个新函数,因此每个实例每次都会创建一个新函数。
  • Boilerplate在写入构造函数中的所有.bind调用,但可以通过_.bindAll
  • 等帮助程序来缓解