什么是';这';请参阅Javascript函数中的
我理解什么是';这';请参阅Javascript函数中的,javascript,Javascript,我理解这个关键字背后的基本思想,但我很难弄清楚它实际上指的是什么。例如,在这两个示例练习中,我猜错了数字 对于问题1,我说警报应该是“5”,因为它指的是函数中匿名函数之外的this.x 在问题2中,我认为警报应该是5,因为这条线 var alertX = o.alertX; 将变量o中属性x的值5绑定到新变量'alertX',该变量将成为下一行中的函数调用:alertX() 你能解释为什么我错了吗 var question1 = function() { this.x = 5;
这个
关键字背后的基本思想,但我很难弄清楚它实际上指的是什么。例如,在这两个示例练习中,我猜错了数字
对于问题1,我说警报应该是“5”,因为它指的是函数中匿名函数之外的this.x
在问题2中,我认为警报应该是5,因为这条线
var alertX = o.alertX;
将变量o中属性x的值5绑定到新变量'alertX',该变量将成为下一行中的函数调用:alertX()
你能解释为什么我错了吗
var question1 = function() {
this.x = 5;
(function() {
var x = 3;
this.x = x;
})();
alert(this.x);
};
var answer1 = 3;
var question2 = function() {
this.x = 9;
var o = {
'x':5,
'alertX':function() { alert(this.x); }
};
var alertX = o.alertX;
alertX();
}
var answer2 = 9;
在第一种情况下,当您在没有显式接收器的情况下调用方法时,此是全局对象(web浏览器中的
窗口
)
类似地,在第二种情况下:即使函数是在对象上定义的,并且您在另一个对象中,通过使用alertx()
调用函数,此
被设置为全局/窗口
简言之:
- 对于
foo.bar()
- 对于
,此bar()
将是全局对象。
- 这包括所谓的“自调用lambda”,即
)(function(){…})(
- 这包括所谓的“自调用lambda”,即
- 对于
和bar.call(whee)
,此bar.apply(whee)
将是
(因为这些方法就是这样做的)whee
var o1 = { name:"o1", f:function(){ console.log(this.name) } };
var o2 = { name:"o2" };
o2.gogogo = o1.f;
o2.gogogo(); // Will output "o2"
这些都是很好的例子,说明了这在Javascript中变得多么有趣这总是指调用/调用它的上下文,而不仅仅是指它当时所在的位置!问题2就是一个很好的例子 我假设您正在全局调用这些函数,如下所示:
question1();
question2();
在问题1中:
您有一个匿名函数,它是在您首次将x设置为5后运行的。此匿名函数如果未设置为变量,则在函数等内部,将此设置为window的全局变量。但是你把它放在一个函数中&设置为变量question1。因此,当它自己运行时,它将这个变量(即问题1函数)x设置为3
在问题2中:
X最初设置为9,在本例中,这是问题2。现在让你感到不舒服的是,即使在o{}对象中,你设置了
x:5
。您的alertX函数正在调用这个.x。所有这些都会让你认为它会提醒5!但是您正在调用o{}对象之外的警报函数,因此this再次引用question2函数 将以下内容放入浏览器的控制台
var x = -1, log = function(){ // set up some stuff
if(console) if(console.log) return console.log.apply(console, arguments),undefined;
return alert(arguments.join(', ')),undefined;
},
question1 = function() {
this.x = 5; // question1.x is 5
(function() { // anonymous function fires in global 'window'
var x = 3; // so window.x is now 3
this.x = x; // this is window
})();
log('ans1',this.x,this); // see below
},
question2 = function() {
this.x = 9; // question2.x is 9
var o = {
'x':5, // o.x is 5
'alertX':function() { log('ans2',this.x,this); }
};
var alertX = o.alertX; // alertX === o.alertX
alertX(); // being called in global scope
// to make alertX have scope of question2
this.alertX = o.alertX; // this is question2
this.alertX(); // so we're calling from question2
},
a1 = new question1(), // note the new operator
a2 = new question2();
undefined;
你会得到
ans1 5 question1
ans2 3 Window
ans2 9 question2
这个
是调用方法的对象,而不是它定义的范围。@32bit,因此,在第一个示例中,e不是调用方法的对象,即外部函数,这表明警报应该是5?我还没有调试这个,但我猜在#1中,这个
将引用窗口
,因此,这两个this.x
都等于window.x
——您首先将window.x设置为5,然后设置为3,因此最新的更新将是3
;但是,在任何时候都不会调用问题1或问题2,因此永远不会出现警报。answer1/answer2是设置数值的变量,因此它们将继续保留这些值:)覆盖得相当好。FWIW:您不知道问题2中的这个实际上设置了什么。我们从未看到如何调用question2()。(虽然它很可能是直接调用的,因此这是一个全局的/窗口
),但从我们知道调用o{}的位置和方式的意义上来说,这并不重要:var-alertX=o.alertX;alertX()代码>在问题2的内部:不完全正确。我们只能排除它不会发出警报5
,但我们无法确定它是否会发出警报9
。在这种情况下,如果问题明确指出它必须是答案之一,那么可能。是的,我指的是它将暗示在这种情况下创建的先前this.x。那么bar.call(whee,woo)呢?那么这是什么?@BeeBand