我在WebKit HTML 5 SQL Storage Notes Demo的源代码中看到了以下内容:

function Note() {
  var self = this;

  var note = document.createElement('div');
  note.className = 'note';
  note.addEventListener('mousedown', function(e) { return self.onMouseDown(e) }, false);
  note.addEventListener('click', function() { return self.onNoteClick() }, false);
  this.note = note;
  // ...
}

作者在某些地方使用self(函数体),在其他地方使用this(在方法的参数列表中定义的函数体)。这是怎么呢现在我已经注意到它一次了,我将开始到处看到它吗?


请在alistapart.com上查看这篇文章。(Ed:文章从最初的链接开始更新)

Self用于维护对原始this的引用,即使在上下文发生变化时也是如此。这是事件处理程序(尤其是闭包)中经常使用的一种技术。

编辑:注意,现在不鼓励使用self作为窗口。Self存在,如果不小心,就有可能导致错误。

你怎么称呼这个变量并不重要。Var that = this;还好,但这名字没什么神奇的。

在上下文中声明的函数(例如,回调,闭包)将可以访问在相同或以上范围中声明的变量/函数。

例如,一个简单的事件回调:

函数MyConstructor(options) { Let that = this; 这一点。Someprop =选项。|| 'defaultprop'; 文档。addEventListener('click', (event) => { 警报(that.someprop); }); } 新MyConstructor ({ someprop:“Hello World” });


该变量由该方法中定义的内联函数捕获。函数中的This将引用另一个对象。通过这种方式,您可以使该函数在外部作用域中保存对This的引用。


是的,到处都能看到。that = this;

看到self是如何在事件调用的函数中使用的吗?它们将有自己的上下文,因此self用于保存进入Note()的this。

尽管self只能在Note()函数完成执行之后执行,但函数仍然可以使用self的原因是,由于闭包,内部函数获得了外部函数的上下文。


还应该注意的是,如果您不喜欢var self = this习惯用法,还有另一种代理模式用于在回调中维护对原始this的引用。

可以使用function在给定的上下文中调用函数。应用或作用调用时,您可以编写一个包装器,该包装器返回一个函数,该函数使用apply或Call使用给定上下文调用您的函数。有关此模式的实现,请参阅jQuery的代理函数。下面是一个使用它的例子:

var包装func = $.proxy代理(这个。myFunc, this);

然后可以调用wrappedFunc,并将此版本作为上下文。


我认为变量名“self”不应该再这样使用了,因为现代浏览器提供了一个全局变量self,指向普通窗口或WebWorker的全局对象。

为了避免混淆和潜在的冲突,可以写成var this = this或var that = this。


实际上self是一个对window (window.self)的引用,因此当你说var self = 'something'时,你重写了对它自己的窗口引用——因为self存在于window对象中。

这就是为什么大多数开发者更喜欢var that = This而不是var self = This;

无论如何;Var that = this;不符合良好的做法…假设您的代码稍后会被其他开发人员修改/修改,您应该使用与开发人员社区有关的最常见的编程标准

因此,你应该使用类似var oldThis / var oThis / etc -的东西来明确你的作用域// ..不是很多,但会节省几秒钟和几次大脑循环


正如上面多次提到的,'self'只是用于在进入函数之前保持对'this'的引用。一旦在函数中,“this”指的是其他东西。


It's a JavaScript quirk. When a function is a property of an object, more aptly called a method, this refers to the object. In the example of an event handler, the containing object is the element that triggered the event. When a standard function is invoked, this will refer to the global object. When you have nested functions as in your example, this does not relate to the context of the outer function at all. Inner functions do share scope with the containing function, so developers will use variations of var that = this in order to preserve the this they need in the inner function.


正如其他人所解释的,var self = this;允许闭包中的代码引用回父作用域。

然而,现在是2018年,所有主要的web浏览器都广泛支持ES6。var self = this;成语不像以前那么重要了。

现在可以避免var self = this;通过使用箭头函数。

在使用var self = this的情况下:

function test() {
    var self = this;
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", function() {
        console.log(self.hello); // logs "world"
    });
};

我们现在可以使用一个没有var self = this的箭头函数:

function test() {
    this.hello = "world";
    document.getElementById("test_btn").addEventListener("click", () => {
        console.log(this.hello); // logs "world"
    });
};

箭头函数没有自己的这一点,只是简单地假定封闭作用域。


function Person(firstname, lastname) {
  this.firstname = firstname;

  this.lastname = lastname;
  this.getfullname = function () {
    return `${this.firstname}   ${this.lastname}`;
  };

  let that = this;
  this.sayHi = function() {
    console.log(`i am this , ${this.firstname}`);
    console.log(`i am that , ${that.firstname}`);
  };
}

let thisss = new Person('thatbetty', 'thatzhao');

let thatt = {firstname: 'thisbetty', lastname: 'thiszhao'};

this.sayHi.call(thatt);