和变量不同关键字this没有作用域限制,this指代运行环境的上下文,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用(全局变量中代表window对象)。
函数在不同的使用场合,其内部的this也会指代不同的对象。
作为普通函数调用
当函数作为普通函数调用的时候this指代window, 在严格模式下指代undefined;
严格模式下
"use strict";
function fn() {
console.log(this)
}
fn() // undefined
复制代码
非严格模式下
function fn() {
console.log(this)
}
fn() // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
复制代码
作为对象的方法调用
当函数作为对象的方法调用时, this指代调用该方法的对象;
var obj = {
name: "hah",
getName: function() {
console.log(this === obj)
}
}
obj.getName() // true
//嵌套函数不会从调用它的函数中继承this
var obj = {
name: "hah",
getName: function() {
console.log(1, this === obj)
console.log(2, this === window)
fn()
function fn() {
console.log(3, this === obj)
console.log(4, this === window)
}
}
}
obj.getName() // 1, true 2, false 3, false 4, true
复制代码
作为构造函数调用
当函数作为构造函数调用时, this指向它新创建的对象。
function Animal(name) {
this.name = name
console.log(this)
}
var cat = new Animal("cat"); // Animal {name: "cat"}
复制代码
bind、call、apply调用时
当函数通过bind、call、apply调用时,会改变内部函数体 this的指向, this指代bind、call、apply传入的第一个参数;
var emptyObj = {}
var obj = {
name: "hah",
getName: function() {
console.log(this === obj)
console.log(this === emptyObj)
}
}
obj.getName.call(emptyObj) // false true
obj.getName.apply(emptyObj) // false true
obj.getName.bind(emptyObj)() // false true
复制代码