JavaScript中的var self = this是什么?

我在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;
// ...
}

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

169609 次浏览

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

self被用来维护对原始this的引用,即使上下文正在改变。这是事件处理程序(尤其是闭包)中经常使用的一种技术。

编辑:注意,现在不鼓励使用self,因为window.self存在,如果你不小心,有可能导致错误。

你怎么称呼这个变量并不重要。var that = this;很好,但是这个名字没有什么魔力。

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

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

function MyConstructor(options) {
let that = this;


this.someprop = options.someprop || 'defaultprop';


document.addEventListener('click', (event) => {
alert(that.someprop);
});
}


new MyConstructor({
someprop: "Hello World"
});

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

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

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

尽管self函数只能在Note()函数完成执行后执行,但它们仍然可用的原因是,由于< em > < / em >关闭,内部函数获得了外部函数的上下文。

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

由于可以使用function.applyfunction.call在给定上下文中调用函数,因此可以编写一个包装器,返回一个使用给定上下文使用applycall调用函数的函数。关于此模式的实现,请参阅jQuery的proxy函数。下面是一个使用它的例子:

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

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

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

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

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

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

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

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

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

这是JavaScript的怪癖。当函数是对象的属性时,更恰当地称为方法,指的是对象。在事件处理程序的示例中,包含的对象是触发事件的元素。当调用标准函数时,将引用全局对象。当你像你的例子中那样有嵌套函数时,与外部函数的上下文完全不相关。内部函数确实与包含函数共享作用域,因此开发人员将使用var that = this的变体,以便在内部函数中保留他们所需的

正如其他人解释的那样,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"
});
};

箭头函数没有自己的this,只是假定外围作用域。

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'};

thisss.sayHi.call(我);