javascript中的范围澄清
简单的问题。为什么我们要设置javascript中的范围澄清,javascript,scope,Javascript,Scope,简单的问题。为什么我们要设置that=this?如果我们不这样做,我们就在全球范围内……但为什么呢 var myObj = { specialFunction: function () { }, anotherSpecialFunction: function () { }, getAsyncData: function (cb) { cb(); }, render: function () {
that=this
?如果我们不这样做,我们就在全球范围内……但为什么呢
var myObj = {
specialFunction: function () {
},
anotherSpecialFunction: function () {
},
getAsyncData: function (cb) {
cb();
},
render: function () {
var that = this;
this.getAsyncData(function () {
// this now refers to global scope....why?
that.specialFunction();
that.anotherSpecialFunction();
});
}
};
myObj.render();
写入
that=this
不会改变范围。匿名函数的调用方式总是以this
作为全局对象结束,*因为使用this=this
只是一种变通方法
您可以使用以下命令使此
始终指向myObj
:
和/或使用:
*除非您处于严格模式,否则在这种情况下,
此
是未定义的编辑:在JavaScript中,“此”上下文取决于函数的调用方式,例如:
function helloWorld()
{
console.log(this);
}
这里有两种调用此函数的方法:
新helloWorld()请注意,如果在此函数中调用函数
这样,这个函数的上下文就是函数的上下文+
原型,因此您的控制台将显示以下内容:helloWorld{}
helloWorld()如果调用函数时没有使用“new”,
“this”的上下文将是全局的(窗口),因此您的控制台将显示
这个:窗口关于:家
好的,有了这个小小的解释,我现在就试着解释你为什么
有时不得不使用self/那
假设您想在this.hello
函数中使用this.name
。正如我前面所说,“this”的上下文取决于函数的调用方式,因此如果要确保this.name在this.hello函数中指的是this.name在函数外部,建议您使用self/that以避免下面发生的情况
function helloWorld(){
var self = this;//or that = this
this.name = "YourName"
this.hello = function(){
console.log(this); //the context of "this" here will be: "hello {}"
return this.name; //undefined, because you don't have name attribute inside hello function
}
new this.hello(); //note how hello is called here...
}
var test = new helloWorld();
下面是关于上下文x范围的一个很好的解释:
看看JavaScript中的this关键字及其工作原理。我相信我们都遇到过这个问题:
$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
}
});
});
这是一个在调用函数时自动为您设置的变量。给定的值取决于函数的调用方式。在JavaScript中,我们有几种调用函数的主要方法。今天我不想全部谈论它们,只想谈谈大多数人使用它们的三种方式;当函数作为方法调用时,或者函数本身调用时,或者作为事件处理程序调用时。根据调用函数的方式,设置方式有所不同:
function foo() {
console.log(this); //global object
};
myapp = {};
myapp.foo = function() {
console.log(this); //points to myapp object
}
var link = document.getElementById("myId");
link.addEventListener("click", function() {
console.log(this); //points to link
}, false);
在(“click”,function(){})上执行$(“myLink”)。意味着当单击元素时,将触发函数。但是这个函数被绑定为一个事件处理程序,所以它被设置为对DOM元素myLink的引用。您在Ajax请求中定义的成功方法只是一个常规函数,因此在调用它时,它被设置为全局对象,就像在调用任何非事件处理程序或对象方法的函数时一样
$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
var _this = this; //store reference
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
console.log(_this); //better!
}
});
});
来源:它在回调函数中。这将改变它。您可以在回调函数中设置断点来检查这个和那个。不确定我是否遵循了您所说的,但我认为如果在块this.getAsyncData中使用“this”,您将引用子对象(this.getAsyncData),但您想要的是访问父对象myObj,它在第一级中被判定为“this”。同样相关:。哦,我知道=这是一个解决方法。我的问题很简单,为什么我们在这一职能的全球范围内。这仅仅是因为它是一个匿名函数吗?“这仅仅是因为它是一个匿名函数吗?”不,这是因为函数的调用方式。在JS中,函数的这个是由调用方决定的(除非使用了函数.bind
。@MattBall不清楚。你如何断言被调用方是窗口对象?@Pilot阅读了我链接的规范@金刚龙-“为什么我们在全球范围内”-你不是。这个值与作用域无关,您在函数作用域中。但是,由于这不是在调用中设置的,它默认为全局对象(或者在严格模式下保持未定义)。您是否故意使阅读您的解释变得困难?FWIW,这个
的工作原理实际上与范围无关。不,显然不是。“这与范围无关”,好吧,如果你说我要和谁竞争?“不,显然不是。”那么你不应该写这么长的评论,我们必须水平滚动。只是把描述放在代码的一边。好的,我已经解决了,现在稍微不粗鲁一点怎么样?抱歉,如果你觉得我粗鲁,那不是我的本意。“指向全局对象。嗯?”实际上不是,根据文档,这个
指的是传递给$.ajax
的选项。这可能有助于作为参考链接来理解。我将尝试看看是否有任何好的例子,以澄清事情容易。顺便说一句,在提供的链接中查找“处理程序中的this值”这个标题我知道this
的工作原理。我只是告诉您,在success
回调中,this
引用传递给$.ajax
的选项,而不是像您所说的那样传递给窗口。所以你选择的例子不是最好的。谢谢克林。我会尽力提供好的例子。:)
function foo() {
console.log(this); //global object
};
myapp = {};
myapp.foo = function() {
console.log(this); //points to myapp object
}
var link = document.getElementById("myId");
link.addEventListener("click", function() {
console.log(this); //points to link
}, false);
$("myLink").on("click", function() {
console.log(this); //points to myLink (as expected)
var _this = this; //store reference
$.ajax({
//ajax set up
success: function() {
console.log(this); //points to the global object. Huh?
console.log(_this); //better!
}
});
});