Javascript 为什么代码指向窗口对象?
我的代码是:Javascript 为什么代码指向窗口对象?,javascript,arguments,this,Javascript,Arguments,This,我的代码是: var length = 20; function fn(){ console.log(this.length); } var o = { length:10, e:function (fn){ fn(); arguments[0](); } } o.e(fn); 输出是20,1,谁能告诉我为什么?当这个关键字出现在函数内部时,它的值取决于如何调用该函数 var length = 20; function fn(){
var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
fn();
arguments[0]();
}
}
o.e(fn);
输出是
20,1
,谁能告诉我为什么?当这个
关键字出现在函数内部时,它的值取决于如何调用该函数
var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
fn(); // this will be the window.
arguments[0](); // this will be arguments object.
}
}
o.e(fn);
在您的情况下,调用fn()
时不提供this值,因此默认值为window
。
对于arguments[0]()
,上下文是arguments
对象,其长度为1
关键是,函数在哪里调用并不重要,但函数如何调用才重要
var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
fn(); // this will be the window.
arguments[0](); // this will be arguments object.
}
}
o.e(fn);
此外,如果希望this
成为对象o
,可以使用call
或apply
,或bind
首先绑定对象
var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
var fn2 = fn.bind(this);
fn.call(this); // this in fn will be the object o.
fn.apply(this); // this in fn will be the object o.
fn2(); // this also will be the object o.
}
}
o.e(fn);
让我们稍微扩展一下代码:
var length = 20;
function fn() {
console.log(this, this.length);
}
var o = {
length: 10,
e: function(fn) {
fn();
fn.call(this);
arguments[0]();
}
}
o.e(fn);
演示:
现在,当调用fn
时,我们可以看到this
是什么(以及this.length
的来源)。这为我提供了以下输出:
DOMWindow 0
Object 10
[function fn() { console.log(this, this.length); }] 1
我们还有三种方法调用函数fn
:
fn()
:只需像调用任何旧函数一样调用它fn.call(this)
:用于强制特定上下文(AKAthis
)arguments[0]()
:通过arguments
对象调用fn
fn()
时,任何地方都看不到this
的显式值,因此,在浏览器中,你会看到窗口
作为你的this
。全局窗口正好有一个:
返回窗口中的帧数(frame或iframe元素)
这就是零(在我的输出中)的来源,您的窗口。长度可能不同
我们把e
称为o.e(fn)
所以这个内部e
是o
,这就是o.e(…)
的意思(禁止有界函数和相关的复杂性)。因此fn.call(this)
中的this
是o
,这使得fn.call(this)
与o.fn=fn相同(或多或少);o、 fn()
我们在控制台中得到o
和10
。注意到那个圆点又出现了吗
调用(o)
类似于o.fn=fn;o、 fn()
第三个变量,arguments[0]()
,包含一个隐藏点,名为p='m';o[p]
与o.m
相同,因此arguments[0]()
类似于fn=arguments[0];arguments.fn=fn;arguments.fn()
阅读一下@muistooshort你说的fn()
和arguments[0]()
,一个调用call
,另一个调用apply
?在第一个调用中,你得到20个this==window
,在第二个this==arguments
。将console.log更改为console.log(this.length,this)代码>和调用o.e(fn,'test')
和您看到的是arguments数组。@dbaseman:这些都是关于使用显式this
执行fn()
的。参数[0]()
的行为是这样的,因为有一个隐藏点,所以有点像说参数.0()
(当然,如果后者是有效的JavaScript)。这不是上下文,它是执行上下文(或ES5中的词汇环境)的一个组件。您应该编写调用fn()时没有提供此值的。调用this
上下文会让人困惑。哦,如果代码处于严格模式,那么会抛出一个类型错误,因为如果没有提供值(它将是未定义的),它不会将this
设置为window
。@RobG Yes,在严格模式下,当dofn()时,这将是未定义的代码>