提问人:Thomas L Holaday 提问时间:6/7/2009 最后编辑:DanManThomas L Holaday 更新时间:11/1/2019 访问量:173548
这个 JavaScript 成语的基础是什么:var self = this?
What underlies this JavaScript idiom: var self = this?
问:
我在 WebKit HTML 5 SQL Storage Notes 演示的源代码中看到了以下内容:
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 的文章。(编辑:本文自最初链接以来已更新)
self
用于保持对原始内容的引用,即使上下文正在更改。这是事件处理程序(尤其是在闭包中)中经常使用的一种技术。this
编辑:请注意,现在不建议使用,因为 window.self
存在,如果您不小心,可能会导致错误。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
this
Note()
尽管函数只能在函数完成执行后才能执行,但函数仍然可用的原因是内部函数由于闭包而获取外部函数的上下文。self
Note()
评论
self
self
var thisNote = this
还应该注意的是,如果您不喜欢这个习语,还有一种替代代理模式用于在回调中维护对原始的引用。this
var self = this
由于可以使用 或 使用给定上下文调用函数,因此您可以编写一个包装器,该包装器返回一个函数,该函数使用给定上下文或使用给定上下文调用您的函数。有关此模式的实现,请参阅 jQuery 的函数。以下是使用它的示例:function.apply
function.call
apply
call
proxy
var wrappedFunc = $.proxy(this.myFunc, this);
wrappedFunc
然后可以调用,并将你的版本作为上下文。this
我认为变量名称“self”不应该再以这种方式使用,因为现代浏览器提供了一个全局变量 self
,指向普通窗口或 WebWorker 的全局对象。
为避免混淆和潜在冲突,您可以改写 或。var thiz = this
var that = this
评论
_this
that
self
var
var
实际上 self 是对 window() 的引用,因此当你说你覆盖窗口对自身的引用时 - 因为 self 存在于 window 对象中。window.self
var self = 'something'
这就是为什么大多数开发人员更喜欢var that = this
var self = this;
无论如何; 不符合良好做法......假设您的代码稍后会被其他开发人员修改/修改,您应该使用开发人员社区中最常见的编程标准var that = this;
因此,您应该使用类似 var / / 之类的东西 - 以便在您的范围内清楚 // ..不是那么多,但会节省几秒钟和几个大脑周期oldThis
var oThis
评论
如上所述,“self”只是用于在进入功能之前保持对“this”的引用。一旦进入函数,“this”指的是其他东西。
评论
这是一个 JavaScript 怪癖。当函数是对象的属性时,更恰当地称为方法,这是指对象。在事件处理程序的示例中,包含对象是触发事件的元素。调用标准函数时,这将引用全局对象。当您具有示例中的嵌套函数时,这与外部函数的上下文完全无关。内部函数确实与包含函数共享范围,因此开发人员将使用 的变体,以便在内部函数中保留他们需要的 this。var that = this
正如其他人所解释的,允许闭包中的代码引用父范围。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"
});
};
我们现在可以使用箭头函数,而无需: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'};
this.sayHi.call(thatt);
评论
this