JS函数中this指向的几道面试题(有趣)
//eg:1
var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
length: 5,
method: function () {
fn();
arguments[0]();
}
}
obj.method(fn, 1);
首先看一下语句结构:
- 一个全局变量
length = 10
; - 一个全局函数
fn()
; 一个全局对象
obj
,并且obj
中有- 1个
length
属性 - 一个
method
方法,在这个method
方法中调用了fn()
和arguments[0]()
;
- 1个
分析完这个结构就要看最后的函数调用,是通过对象obj
的一个方法进行调用的,这个时候就存在一个函数中的this
指向问题.
在obj.method
中的第一个fn()
函数,最终this
的指向是外部的window
顶级对象,那么第9行的fn()
执行后会访问全局变量length
返回10;
而第二步arguments[0]()
是以传入的第一个参数为函数执行的>>也就是fn(),
这个时候的知识点就是:this指向 谁调用指向谁,谁最后调用指向谁;
案例中通过object对象调用method方法,最后的调用者就是method 相当于 obj.method.arguments[0]();
既然这个时候的this的指向是method
方法的参数伪数组,输出arguments
的参数length,也就是fn和1 总长度为2;
所以在控制台输出之后的输出结果是
10;
2;
为了进一步查看思路是否正确可以把外部的fn()修改为:
function fn() {
console.log(this);
console.log(this.length);
}
执行后控制台输出
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
10
Arguments(2) [ƒ, 1, callee: ƒ, Symbol(Symbol.iterator): ƒ]0: ƒ fn()1: 1callee: ƒ ()length: 2Symbol(Symbol.iterator): ƒ values()__proto__: Object
2
//eg:2
var b = 1;
function outer() {
var b = 2
function inner() {
b++;
var b = 3;
console.log(b)
}
inner();
}
outer();
结构:
- 一个全局变量
b
; 一个全局函数
outer()
;- 在outer()里又声明和调用了一个inner()函数
最后调用函数outer();
按照结构来看的话,其实这就一个函数内部变量提升、访问的问题,从调用了outer()之后,就从代码的第3-11行进行了编译执行,首先是第7行的局部变量b进行变量声明提升,所以在inner()函数体中的实际顺序为:
function inner(){
var b;
b++; //因为只有声明提升了,赋值没有提升,那么b++之后的返回结果是:undefined;
b = 3; //重新给b赋值:b =3;
console.log(b); //3
}
inner();
所以在控制台输出之后返回结果是:3
;
在这个题里,涉及到的知识点是:
- 函数内部变量声明提升,赋值并不提升
- 函数内部使用的变量会优先从函数体内部进行查找,如果查找到的话即使用,如果内部查找不到才会访问外部环境进行查找
我后面会陆陆续续的丰富一些js的常用面试题,旨在分享和交流,如果有什么地方说的不太准确,欢迎各位留言评论发表意见(友善的发言会给人带来好运哦 ^ ^)