面试时,JavaScript中有个this关键字,经常被面试官问道指向谁。。。
这个this关键字一会指向window、global、一会儿又指向刚刚new出来的新对象。
很多人都知道"this指向的是函数执行的环境对象。",这要怎么理解?
"this"关键字应用的场景。
场景一:函数调用
function a() {
console.log(this);
}
a(); //window
在浏览器中,a的执行环境即为window,所以this指向了window。
场景二:方法调用
let obj = {
b: function () {
console.log(this);
}
}
obj.b();
当作为对象的方法时,函数的this指向其所属对象。
场景三:构造函数
window.age = 100
function GirlFriend() {
this.age = 22;
}
const girlFriend = new GirlFriend()
console.log(girlFriend.age);
从girlFriend.age为22可以看出,以构造函数的形式执行函数时,this指向其返回的对象。
场景四:改变this指向
window.hello = 'hello ,window'
let obj = {
hello: 'hello,obj'
}
function sayHello() {
console.log(this.hello);
}
sayHello();
sayHello.call(obj);
sayHello.apply(obj);
const hi = sayHello.bind(obj);
hi();
call 方法和 apply 方法接收的第一个参数,是一个为函数指定的 this. 上面的代码中,第一次函数调用形式执行 sayHello, this 指向的是 window. 后面的 call 和 apply 指定的 this 是对象 obj, sayHello 函数执行这两个方法时,this 指向了 obj.
bind 方法的第一个参数也是指定的 this, 执行 bind 方法,返回一个拥有指定 this 的函数。上面代码中的 hi 指向一个函数,这个函数是 this 为 obj 的 sayHello.
场景五:箭头函数
window.hello = 'hello ,window'
let obj = {
hello: 'hello,obj',
foo: function () {
return () => {
console.log(this.hello)
}
}
}
let a = obj.foo();
a();
let b = obj.foo;
let c = b();
c();
箭头函数没有自己的 this, 当箭头函数内部出现 this, 可将它理解为一个变量——“我没有这个变量,去我的外面一层找一找有没有”。所以,箭头函数的 this, 指向的是定义箭头函数时的外部环境。
上面代码中,对象 obj 的方法 foo, 返回一个箭头函数,该箭头函数打印 this.hello.
变量 a 的值是 obj.foo() 的返回值,即为箭头函数。obj.foo() 是方法调用,此时,foo 的 this 指向的是对象 obj. 而 foo 中的箭头函数用到的 this 是从箭头函数的外部(即 foo)拿到的,也指向 obj.
对象 obj 的 foo 赋值给了变量 b, let b = obj.foo 相当于下面的代码:
let b = function () {
return () => {
console.log(this.hello);
}
}
接下来执行 b, 把返回的箭头函数赋值给 c. 此时,执行 b 是一次函数调用,函数 b 的 this 指向的是它的运行环境 window. 箭头函数拿到的 this, 是它外层函数的 this, 也就是 window.
场景六:严格模式下
'use strict'
window.hello = "Hello, I am window."
function sayHello() {
console.log(this.hello);
}
sayHello();
严格模式下,函数调用的场景会受到影响。这个时候,函数内的this不再指向全局对象。
总而言之:this指向函数执行的环境条件。