简体   繁体   English

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

[英]Why would you create a variable with value this

I've seen this done alot in JavaScript and I do remember finding out why but I can't remember the answer. 我已经在JavaScript中看到了很多这样做,我确实记得找出原因,但我记不起答案了。

I'm guessing it's something to do with scope and a function being called outside the "class" but why would one do this (preferably outlining an example): 我猜这是与范围和在“类”之外调用的函数有关,但为什么会这样做(最好勾勒出一个例子):

function myClass ()
{
    var self = this;

    //...

    this.myArray = [];

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

In order to latch onto the variable as part of a closure . 为了作为闭包的一部分锁定变量。

For example: 例如:

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() );
  });
};

The specific example you wrote does not need a closure if you invoke the method in the expected way: 如果以预期的方式调用方法,则您编写的特定示例不需要闭包:

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

However, it's possible to 'break' it like so: 但是,它可以像这样“打破”它:

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

Your code using the closure, on the other hand, is safe against this sort of tomfoolery. 另一方面,使用闭包的代码可以安全地防止这种愚蠢行为。

"this" refers to the current "object". “这”指的是当前的“对象”。 The power resides, when talking about javascript, into the fact that the "this" expression is evaluated context-wise, so for example if a method is executed in another object context, the "this" value will change respectively. 在谈论javascript时,权力存在于“this”表达式在上下文中被评估的事实,因此例如如果在另一个对象上下文中执行方法,则“this”值将分别改变。

If you create a function within another function, this for the inner function gets set to the global window object. 如果在另一个函数中创建函数,则内部函数的this函数将设置为全局窗口对象。 If you create a variable saving the value of this , like 如果你创建一个变量保存的值this ,像

var that = this;

then you can use that to reference the outer function within the inner function. 然后你可以用that来引用内部函数中的外部函数。

In addtion to some of the answers posted by other users, creating variable set to this allow you to reuse variables without accessing objects. 除了其他用户发布的一些答案之外,创建设置为此的变量允许您在不访问对象的情况下重用变量。

Similar to doing something like: 做类似于:

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

And then accessing myElement if you need to rather than document.getElementById multiple times. 然后,如果您需要多次而不是document.getElementById,请访问myElement。

Setting that = this or self = this gives you access everywhere to "that" or "self" and prevents from re-loading some object. 设置= this或self =这使您可以访问“that”或“self”的所有位置,并防止重新加载某些对象。

I don't think one really wants to do that: 我不认为有人真的想这样做:

  • Any time an instance is created, you also create a "copy" of the function. 无论何时创建实例,您还可以创建该函数的“副本”。 So 5 instances, will create 5 "copies" of the function. 所以5个实例,将创建5个“副本”的功能。
  • That "copy" of a function is bound to an environment that is only relevant to that specific instance, so it cannot be used generically. 函数的“复制”绑定到仅与该特定实例相关的环境,因此不能一般地使用它。 That means an extending class will get a method that is only relevant for some instance of the parent class that is probably not even used. 这意味着扩展类将获得一个方法,该方法仅与可能甚至不使用的父类的某个实例相关。
  • Your indentation will get out of hand especially if you start nesting those inline functions 如果您开始嵌套这些内联函数,您的缩进将失控
  • You'll have to hunt for functions inside other functions instead of just looking it up in the prototype definition 你必须在其他函数中寻找函数,而不是仅仅在原型定义中查找它

An alternative: 替代:

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

A few drawbacks: 一些缺点:

  • Each bound function is a new function so per instance, 1 new function is still created every time. 每个绑定函数都是一个新函数,因此每个实例每次仍然会创建一个新函数。
  • Boilerplate in writing out all the .bind calls in the constructor, though can be mitigated with a helper like _.bindAll Boilerplate在构造函数中写出所有.bind调用,虽然可以使用像_.bindAll这样的帮助器来缓解

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM