“var self = this”方法背后的原理是什么?
What is the rationale behind the "var self = this" approach?
在可能的重复项:
JS:var self = this?
查看用 JavaScript 编写的任意代码(例如在 GitHub 上)时,许多开发人员使用 var self = this
,然后使用 self
而不是 this
来引用当前对象。
这种方法背后的理由是什么?
this
的值是上下文相关的。编写var self = this
是一种将this
的值保存在一个上下文中以便可以在另一个上下文中使用的方法。
例:
function Test() {
var self = this;
console.log(this);
setTimeout(function() {
console.log(this);
console.log(self);
}, 1000);
}
指纹:
Test {}
Window 11918143#comment15869603_11918143
Test {}
请注意,this
的值已更改,但我们仍然可以使用 self
引用原始值。
这是有效的,因为 JavaScript 中的函数"关闭"其词法范围内的变量(这只是一种更技术性的说法,即内部函数可以看到外部函数中声明的变量)。这就是我们写var self = this
的原因;变量 self
可用于所有内部函数,即使这些函数直到外部函数返回很久后才执行。
例如,当您在 jQuery 中使用回调时,您可能希望引用父函数的 this
变量,该变量在另一个函数中后采用不同的值:
$('#foo').click(function() {
var self = this;
$.get('foo.php', function(data) {
// In here, self != this
$(self).text(data);
});
});
在这种情况下,将$(self)
替换为$(this)
将不起作用。基本上,您将this
存储在变量中以供以后使用。
通常,当您在某些代码中具有嵌套函数声明,但您想从"子"函数内部引用"parent"函数时。
Ext.define('MyPanel', {
extend: 'Ext.panel.Panel',
title: 'My Panel',
initComponent: function() {
var self = this;
Ext.applyIf(self, {
items: [
{
xtype: 'button',
text: 'MyButton',
handler: function() {
console.log(this); //the button
console.log(self); //the panel
}}
]
});
self.callParent(arguments);
}
});
Ext.onReady(function() {
var p = new MyPanel({
renderTo: Ext.getBody()
});
});
例:
http://jsfiddle.net/8F4UN/
让我给出一个更技术性的解释。当您在 Javascript 中访问变量时,解释器会在所谓的作用域堆栈中查找变量的值。您可以将其视为一堆对象。解释器将首先查看堆栈的顶部。如果未在该范围对象中定义变量,它将查看其下的对象。如果它不存在,解释器会向下看另一层,直到它到达堆栈的底部。
最初,堆栈中唯一的范围对象是全局对象。变量要么存在,要么不存在。调用函数时,解释器将一个新对象推送到作用域堆栈上,用于存储局部变量。当您访问 var1 时,解释器将首先查看本地作用域对象。如果它在那里,那么它将使用存储在那里的值。如果不是,它将移动到堆栈中更下方的 scope 对象,这恰好是全局范围。
当您在函数中创建函数时,会发生一些有趣的事情。解释器将创建所谓的"激活对象"。它基本上是外部函数的本地作用域对象的快照。此激活对象与内部函数相关联。调用内部函数时,激活对象被推到本地作用域之前的作用域堆栈上(即本地作用域仍将位于顶部)。访问内部函数中的变量意味着解释器将首先检查局部作用域对象,然后检查激活对象,然后检查全局作用域对象。
根据定义,this 变量始终存在于函数的局部作用域中。它始终引用隐式的第一个参数。调用 plain-o 函数时,编译器将按此方式传递 null。变量存在,但指向 null。对此的搜索永远不会超出本地范围对象。
分配给 self 的目的基本上是愚弄解释器,这样它就会超越内部函数的局部范围。当您在内部函数中访问 self 时,解释器不会在本地范围内找到它。因此,它会检查激活对象。假设 self = 此语句发生在创建内部函数之前,则 self 将存在于激活范围对象中,指向外部函数看到的 this 对象。
- “var self = this”方法背后的原理是什么?
- React Router 如何处理 onEnter 背后的逻辑是什么?
- 让函数中的接收器默认为全局对象背后的基本原理是什么?
- AJAX 跨域安全背后的基本原理是什么?
- Facebook评论API - Facebook所说的“评论框背后”是什么意思
- Lightstreamer背后的魔力是什么
- d3背后的逻辑是什么.js nice()刻度
- JavaScript:“shift”方法背后的逻辑是什么?
- Math.max方法背后的逻辑是什么
- 与compareFunction一起使用的排序方法背后的逻辑是什么
- 用continuation生成Javascript代码背后的诀窍是什么
- 窗口背后的原因和窗口的顶部属性是什么
- 名称空间背后的概念是什么
- 堆栈溢出背后的算法是什么? ajax标记搜索字段
- 网站上的3D图像非常酷,但这背后的技术是什么?
- 使用Object.assign创建对象背后的思想是什么?
- canPlayType背后的原理是什么?
- javascript中var a = (expression1, expression2)背后的原因是什么?
- 错误处理-当JavaScript抛出ReferenceError时,其背后的逻辑是什么
- 选择一个完整的基于CSS的菜单和基于Javascript/CSS的菜单背后的基本原理是什么?