我的代码是:
var length = 20;
function fn(){
console.log(this.length);
}
var o = {
length:10,
e:function (fn){
fn();
arguments[0]();
}
}
o.e(fn);
输出为20,1
,谁可以告诉我原因?
答案 0 :(得分:6)
当this
关键字出现在函数内部时,其值取决于函数的调用方式。
在您的情况下,调用fn()
时不会提供此值,因此默认值为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
对象。< / p>
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);
答案 1 :(得分:2)
让我们稍微扩展您的代码:
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);
演示:http://jsfiddle.net/ambiguous/Ckf2b/
现在,我们可以在调用this
时看到this.length
是什么(以及fn
来自何处)。这给了我以下输出:
DOMWindow 0
Object 10
[function fn() { console.log(this, this.length); }] 1
我们还有三种方法来调用函数fn
:
fn()
:只需将其称为任何旧功能。fn.call(this)
:使用call
强制使用特定的上下文(AKA this
)。arguments[0]()
:通过fn
对象致电arguments
。当您说fn()
时,this
没有任何明确的价值,因此,在浏览器中,您会window
作为this
。全球window
碰巧有length
property:
返回窗口中的帧数(frame或iframe元素)。
这就是零(在我的输出中)来自的地方,您的window.length
可能会有所不同。
我们将e
称为o.e(fn)
,this
e
内的o
为o.e(...)
,这就是this
的含义(禁止约束函数和相关复杂性) )。因此fn.call(this)
中的o
为fn.call(this)
,o.fn = fn; o.fn()
与o
相同(或多或少),我们得到10
和{控制台中的{1}}。注意点再次出现?
类似
fn.call(o)
与o.fn = fn; o.fn()
第三个arguments[0]()
包含隐藏点,因为p = 'm'; o[p]
(或多或少)与o.m
相同,因此arguments[0]()
就像fn = arguments[0]; arguments.fn = fn; arguments.fn()