我在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 (在方法的参数列表中定义的函数体)。这是怎么回事?现在我已经注意到它了,我会在各处开始看到它吗?
答案 0 :(得分:419)
self
用于维护对原始this
的引用,即使上下文正在发生变化。这是一种常用于事件处理程序的技术(特别是在闭包中)。
答案 1 :(得分:96)
我认为变量名'self'不应再以这种方式使用了,因为现代浏览器提供了一个global variable self
指向普通窗口或WebWorker的全局对象。
为避免混淆和潜在冲突,您可以改为编写var thiz = this
或var that = this
。
答案 2 :(得分:34)
是的,你会在任何地方看到它。通常是that = this;
。
了解如何在事件调用的函数中使用self
?这些将有自己的上下文,因此self
用于保存this
中的Note()
。
self
仍然可用于函数的原因,即使它们只能在Note()
函数执行完毕后才能执行,因为内部函数由于 闭合 强>
答案 3 :(得分:28)
还应该注意,如果您不喜欢this
成语,则可以使用另一种代理模式来维护对回调中原始var self = this
的引用。
由于可以使用function.apply
或function.call
使用给定的上下文调用函数,因此可以编写一个包装器,该函数返回一个函数,该函数使用apply
或{{1使用给定的上下文。有关此模式的实现,请参阅jQuery的call
函数。以下是使用它的示例:
proxy
var wrappedFunc = $.proxy(this.myFunc, this);
,并将您的wrappedFunc
版本作为上下文。
答案 4 :(得分:9)
该变量由方法中定义的内联函数捕获。函数中的this
将引用另一个对象。这样,您可以使该函数保留对外部范围中this
的引用。
答案 5 :(得分:9)
这是一个JavaScript的怪癖。当一个函数是一个对象的属性时,更恰当地称为一个方法,这个引用该对象。在事件处理程序的示例中,包含对象是触发事件的元素。调用标准函数时,此将引用全局对象。如示例所示,当您具有嵌套函数时,此根本不与外部函数的上下文相关。内部函数与contains函数共享范围,因此开发人员将使用var that = this
的变体来保留内部函数中所需的 this 。
答案 6 :(得分:7)
正如其他人所解释的那样,var self = this;
允许closure中的代码引用回父范围。
然而,它现在是2018年,ES6得到了所有主要网络浏览器的广泛支持。 var self = this;
成语并不像以前那么重要。
现在可以通过使用arrow functions来避免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
,只是假定封闭范围。
答案 7 :(得分:5)
实际上self是对窗口(window.self
)的引用,因此当你说var self = 'something'
覆盖对自身的窗口引用时 - 因为self存在于window对象中。
这就是为什么大多数开发人员更喜欢var that = this
而不是var self = this;
反正; var that = this;
与良好实践不一致......假设您的代码稍后会被其他开发人员修改/修改,您应该使用与开发人员社区相关的最常见的编程标准
因此你应该使用像var oldThis
/ var oThis
/ etc这样的东西 - 在你的范围内清楚// ..不是那么多,但会节省几秒钟和几个脑循环
答案 8 :(得分:0)
如上所述,“self”只是用于在进入函数之前保持对“this”的引用。一旦进入函数'this'指的是其他东西。
答案 9 :(得分:-1)
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(thatt);