看到一些不错的this面试题,总结下来:
当一个函数被调用时,会创建一个活动记录(有时候称为执行上下文),这个记录包含函数在哪里被调用(调用栈)、函数的调用方式以及传入的参数等信息,this就是这个记录的一个属性,会在函数执行的过程中用到。
this既不指向函数自身也不指向函数作用域,它是在函数被调用时绑定的,指向什么完全取决于函数在哪里被调用。
1,
var obj = { a: 10, b: this.a + 10, fn: function () { return this.a; } } console.log(obj.b); console.log(obj.fn());
这题答案是
// NaN // 20
有意思的是这个第一个解为什么是NaN,原因是看this的执行时机,b属性里的this实际上在obj定义的时候就执行了,所以此时this指向了window,而fn里的this是fn执行的时候才会去查找this,因此根据最开始红色的字体,可以知道结论。
2,
function fn( ) { 'use strict'; var a = 1; var obj = { a: 10, c: this.a + 20 } return obj.c; } console.log(fn());
这题答案是
//输出报错==》 a undefined
原因同上一题,看this的绑定时机,但是因为是严格模式下,所以this.a报错了
3,
// 声明一个构造函数 function Person(name, age) { this.name = name; this.age = age; console.log(this); } Person.prototype.getName = function () { console.log(this); }; var p1 = new Person("test", 18); p1.getName();
这道题的答案是
// 打印出来都是构造函数Person
4,
var obj = { foo: "test", fn: function(){ var mine = this; console.log(this.foo); //test console.log(mine.foo); //test (function(){ console.log(this.foo); //undefined console.log(mine.foo); //test })(); } }; obj.fn();
这题的答案在题目里了
前两个就不解释了,后两个:
第一个this.foo,因为立即执行函数,执行者就是window,所以this指向window
第二个,mine是之前保留了上一个this的指针,因此它依然保留着上一个this所指向的当前执行环境obj,因此mine.foo依然是test
5,
function test(arg) { this.x = arg; return this; } var x = test(5); //此时 x = window, y = undefined var y = test(6); //此时 x = 6, y = window , 后面申请的x会覆盖掉第一次在this.x 生成的window.x console.log(x.x); //undefined, 实际上是6.x 是undefined console.log(y.x); //6 实际上是window.x 也就是6
这道题的解析和答案都在里面了
主要是x.x,因为定义y的时候,x被修改了,所以x此时就是6了,因此x.x就没有值了
6,
var a = document.querySelector; a('#main');
为什么上面执行会报错?
因为querySelector是根据文档document去查找的,所以内部应该是使用了this的指针,指向document,而a('#main')等同于将this指向了window,所以会报错
end