var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
问题1:method中的this指向obj,因为obj对象调用了method。
问题2:arguments[0]是fn,但是此时this指向arguments,因为arguments对象调用了fn。
问题一,函数中的this要看在调用哪的,不是看在哪声明的。
如果call改变this指向就输出5
var obj = {
length: 5,
method: function(fn) {
fn.call(this);//输出5
arguments[0]();
}
};
问题二,arguments[0]就是fn没错,是指 obj.method(fn,1);实参中的第0个也就是fn。他的this指向实参,返回的是实参的个数。
obj.method(fn,1,2,3,4,5);// 输出6
10的话应该很好理解的 和上面大佬说的只是被调用了 并没有更改上下文
至于为什么是2,你可以在fn这个函数里面添加console.log(this),把this指针打印出来看看是什么,另外有一个点事 arguments是函数内部的参数数组,数组其实就是对象,对象内部的函数的this指针指向的是这个对象,那么同理 数组中的某一项如果是函数的话,那么这个函数的上下文this指针就指向的是这个数组
问题 1:
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
}
};
obj.method(fn, 1);
题主需要理解 this 的指向问题, obj.method 中的 method 的 this 指向确实是 obj, 但是里面的 fn 是传参进去的, 在 javascript 中传参都是值传递,对象是特殊的值传递也就是共享传递,也就是传进去的是对象的引用地址,函数是特殊的对象,所以你在 obj.method 函数体里面执行 fn 和在函数体外面执行 fn 是一样的,此时 this 指向是 window 对象。
fnRefenerce {
identifier: fn,
base: window
}
问题 2:
arguments[0] 确实是传进来的 fn 函数这个没错,但是需要注意的是, 现在是通过 arguments 对象去调用 fn 函数, 函数是一个对象, 是一个引用值:
fnRefenerce {
identifier: fn,
base: arguments
}
this 的指向是动态的, 需要看调用函数的时候的引用情况, 通过 arguments 对象调用的就像上面的伪代码一样, this 就指向了引用的 base 值,那么 arguments[0] 调用就是打印出了 arguments.length, 这里就是 arguments 的参数长度, 输入了两个参数:fn 和 1, 所以是 2.
长见识了....
var arr=[function(){console.log(this===arr)}]
arr[0]() // true
var q = arr[0];
q() // false
arguments相当于这里的arr,数组内部的元素,如果是一个function,那么直接调用这个function时 内部this指向的是数组。
所以说JS奇葩呢。
怎么这么多this的问题。。?
建议你看一看《你不知道的javascript》中"this & Object Prototypes"这一章节,this的指向讲得清清楚楚,没那么复杂:
1.函数是否由new 调用:如果是,指向新创建的对象;
2.是否显示绑定对象:即apply, call, bind, arrow function,如果是,this指向绑定的对象;
3.是否隐式绑定:即是否存在上下文context(被某一对象调用),如果是,this指向绑定的对象;
4.其余情况:非严格模式下,指向global,严格模式下,不能指向global, this为undefined
用此规则分析你的问题:
1.虽然method是被obj调用,存在上下文,但是fn函数本身并不存在上下文(它不是被某对象调用),因此fn的this指向global;
稍微修改一下:
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
console.log(this.length) //添加此行
fn();
arguments[0]();
}
};
obj.method(fn,1)
> 5,10,2
2.arguments[0]确实就是fn,但此时fn由arguments调用,因此this指向arguments,和我上面修改了一点的代码会先输出一个5一样的道理
ps:很多时候会有这些说法:谁调用指向谁,从结果来看正确但对新手来说不够清楚,因为新手不一定能分析清楚到底是谁“调用”的,比如
window.age = 18
let obj = {
age: 88,
showAge() {
console.log(this.age)
}
}
let showAge = obj.showAge
showAge() // 18
不先回答问题的都是耍流氓!!先回答提主问题,Q1:不是!;Q2:是!稍安勿躁,下面解释为什么。
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
首先,this的指向问题是分情况的!!!
首先,this的指向问题是分情况的!!!
首先,this的指向问题是分情况的!!!
重要的事说三遍~~~
JavaScript中函数调用分四种情况:
具体例子不展开了,请看犀牛书P168~谢谢!
分析一下代码,首先在全局环境即window环境中定义了变量length,函数fn,对象obj;在obj对象中定义了length属性和method方法;
在执行 obj.method(fn, 1)
后(这是方法调用),该操作下首先执行了 fn()
,这属于函数调用,函数调用中的this值指向全局对象window,此时输出this.length相当于window.length,最后结果是10。
紧接着执行arguments[0]()
的操作。这里首先明白一个概念arguments是一个对象!arguments是一个对象!arguments是一个对象!只不过这个实参对象碰巧具有以数字为索引的属性。这里是最容易让人产生误区的地方,也是面试题中经常晃点你的地方!你可以把它理解成这样一个对象arguments = {1:fn,2:1,length:2}
,既然arguments是一个对象,那么arguments[0]()
可以理解为这样arguments.0()
即arguments.fn()
。因此,这里是一个赤果果的方法调用啊!同学们!而函数方法调用中的this值指向调用该方法的对象!输出的this.length
就是arguments.length
,最后调用传了两个实参fn和1,因此输出是2。
回答的有点啰嗦了,希望大家能看懂,也欢迎大家及时指正!怀念在美团做数据运营的日子~~~
function中的this通常只与其声明所在的作用域有关,改变function的this指向的方式有apply,call,bind,new XXX()或指定函数的上下文对象,所以
1、method中直接执行fn()并不影响this的指向,this仍然指向window
2、函数中的arguments指向当前所在函数,所以arguments[0]中的this指向method方法而不是obj
第一个没加.或者[],且不是严格模式。this指向window.
第2个arguments[0](),有[],this指向[]前面的arguments对象,而arguments.length返回的是实参的长度。返回2。如果method方法里添加arguments.callee.length则返回1,函数的length属性返回形参的长度。
简单理解非严格模式下的this:只要不是通过.或者[]调用函数,this就指向window。反之this就指向.或者[]前面的对象(不严谨的说法,解决一般的问题够用了,注意"链式调用",call、apply、bind)
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
this绑定一般有4种方式,即
总结:一,如果函数独立运行,this指向 undefined;
二,如果函数被某个对象拥有,this指向那个对象。
拿例子来说:
var obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
fn定义的时候是独立函数,运行也是独立函数;所以 this是undefine。运行的时候发现this并不是undefine,是存在的。那是因为浏览器有点特别,函数虽然独立运行,但是他在 window对象下面。正好符合规则2,函数被对象所拥有,this应该指向对象(window);当然 如果在node里面或者严格模式下,this就是undefine了
arguments[0]() 同理可知,函数被arguments 拥有,所以this指向arguments
13 回答13.1k 阅读
7 回答2.3k 阅读
3 回答1.4k 阅读✓ 已解决
6 回答1.5k 阅读✓ 已解决
2 回答1.5k 阅读✓ 已解决
3 回答1.5k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
第一个问题
这样你就看的明白些了;
第二个,arguments[0]()this指向arguments,返回的就是arguments的长度