大前端之关于this(看完以后再也不用担心this了)
this三连问
-
下面的this指向谁?
const obj1 = { foo: function () { console.log(this) } }
答案:指向谁都有可能,可能是全局,可能是obj1,这取决于它如何被调用,而不是取决于它被定义时的位置。
-
下面的this指向谁?
const obj2 = { foo: function () { function bar () { console.log(this) } bar() } } obj2.foo()
答案:this指向全局。
是不是有疑问,不是说谁调用就指向谁么?应该是obj2呀?
如果没有bar函数,直接打印foo函数的this,确实是指向的obj2。 -
下面的this指向谁?
var length = 10 function fn () { console.log(this) // console.log(this.length) } const obj = { length: 5, method (fn) { fn() // => window 10 arguments[0]() // => arguments 3 } } obj.method(fn, 1, 2)
答案:看注释
此题的核心是argument0,argument是实参列表,并且是个伪数组,我们可以将argument[0]看成对象中的属性:argument.0,因为argument[0] = fn,所以此时this就指向的是argument,而length自然是3(实参列表)
最后,关于 this 的总结:
- 沿着作用域向上找最近的一个 function(不是箭头函数),看这个 function 最终是怎样执行的;
- this 的指向取决于所属 function 的调用方式,而不是定义;
- function 调用一般分为以下几种情况:
- 作为函数调用,即:foo()
- 指向全局对象,注意严格模式问题(严格模式下指向undefined)
- 作为方法调用,即:foo.bar() / foo.bar.baz() / foo[‘bar’]
- 指向最终调用这个方法的对象
- 作为构造函数调用,即:new Foo()
- 指向一个新对象 Foo {}
- 特殊调用,即:foo.call() / foo.apply() / foo.bind()
- 参数指定成员
- 作为函数调用,即:foo()
- 找不到所属的 function,就是全局对象