这个JavaScript成语的基础是:var self = this?

Tho*_*day 353 javascript closures scope

我在WebKit HTML 5 SQL存储笔记演示的源代码中看到以下内容:

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;
  // ...
}
Run Code Online (Sandbox Code Playgroud)

笔者采用自我在一些地方(函数体)及在其他地方(的函数方法的参数列表中定义的机构).这是怎么回事?现在我已经注意到了它,我会在各处开始看到它吗?

Jon*_*and 427

请参阅alistapart.com上的这篇文章

self用于维护对原始的引用,this即使上下文正在发生变化.这是一种常用于事件处理程序的技术(特别是在闭包中).

  • 感谢指向优秀文章的指针. (29认同)

Dua*_*Yao 96

我认为变量名'self'不应再以这种方式使用,因为现代浏览器提供了一个指向普通窗口或WebWorker的全局对象的全局变量self.

为了避免混淆和潜在的冲突,你可以写var thiz = thisvar that = this代替.

  • 我通常使用`_this` (42认同)
  • 使用名称`self`绝对没有问题,只要你将它声明为`var`iable,它就会影响全局.当然如果你忘了`var`那么它也不能用于任何其他名字. (10认同)
  • 我开始使用"我":) (9认同)
  • @djheru +1.比"那个"更好(我的大脑永远不会习惯). (6认同)
  • 直到现代浏览器开始提供全局变量_this,that或者我. (3认同)

Nos*_*dna 34

是的,你会在任何地方看到它.经常这样that = this;.

了解如何self在事件调用的函数内部使用?那些会有自己的背景,因此self习惯于持有thisNote().

原因self仍然可用于函数,即使它们只能在Note()函数执行完毕后执行,内部函数是否因为闭包而获得外部函数的上下文.

  • 对我来说,有用的一点是"自我"没有特别的意义.我个人更喜欢使用一个名为"self"之外的var,因为它常常让我感到困惑,因为我希望'self'成为一个保留词.所以我喜欢你的回答.在OP的例子中,我更喜欢`var thisNote = this`或类似的. (12认同)

Max*_*Max 28

还应该注意的是,this如果你不喜欢这个var self = this习语,还有另一种代理模式可以在回调中维护对原文的引用.

作为一个功能可以与特定背景下,通过使用被称为function.apply或者function.call,你可以写一个返回与调用你的函数功能的包装applycall使用给定的范围内.请参阅jQuery的proxy函数以实现此模式.以下是使用它的示例:

var wrappedFunc = $.proxy(this.myFunc, this);

wrappedFunc然后可以调用,并将您的版本this作为上下文.


Meh*_*ari 9

该变量由方法中定义的内联函数捕获.this在函数中将引用另一个对象.这样,您可以使该函数保持this对外部作用域的引用.


kom*_*bat 9

这是一个JavaScript的怪癖.当一个函数是一个对象的属性时,更恰当地称为一个方法,指的是该对象.在事件处理程序的示例中,包含对象是触发事件的元素.调用标准函数时,将引用全局对象.当您在示例中具有嵌套函数时,根本不涉及外部函数的上下文.内部功能并分享与含功能范围,因此开发人员使用的变化var that = this,以保持,他们在内部功能的需要.


Ell*_* B. 8

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

但是,它现在是2018年,ES6得到了所有主流Web浏览器的广泛支持.这个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"
    });
};
Run Code Online (Sandbox Code Playgroud)

我们现在可以使用箭头功能而不var self = this:

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

箭头函数没有自己的this,只是假设封闭范围.

  • 在JavaScript中,回溯到父范围是非常普遍和必要的。这是语言的基本组成部分。您实际上不建议将父范围作为事件处理程序的参数传递。另外,在ES6中,箭头函数使用词法作用域-“ this”是指当前范围,而不是进一步的范围,不是“引用超出范围状态”之类的东西。 (2认同)

小智 5

实际上self是对window(window.self)的引用,因此当你说var self = 'something'你覆盖对它自己的窗口引用时 - 因为self存在于window对象中.

这就是为什么大多数开发人员更喜欢var that = thisvar self = this;

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

因此你应该使用类似var oldThis/ var oThis/ etc之类的东西- 在你的范围内清楚// ..不是那么多,但会节省几秒钟和几个脑循环

  • @prior我认为直到最后一段才有意义. (2认同)
  • @miphe为什么?最后一段有什么问题? (2认同)