this
谁调用它,this就指向谁,也就是说this的指向是在调用时确定的。
事实上调用函数会创建新的属于函数自身的执行上新闻。执行上下文的调用创建阶段会决定this的指向。
总结:this的指向,是在调用函数时根据执行上下文所动态确定的。
1)一般构造函数new调用,绑定到新创建的对象上
2)一般由call/apply/bind方法显示调用,绑定到指定参数的对象上
3)一般由上下文对象调用,绑定在该对象上
4)箭头函数中,根据外层上下文绑定的this决定this指向
5)函数体重,简单调用该函数是(非显示/隐式绑定下),非严格模式下绑定到全局对象window/global,严格模式下绑定到undefined。
//1.全局环境下的this
function f1(){
console.log(this)
}
f1() // window
function foo={
bar:10,
fn:funciton(){
console.log(this)
console.log(this.bar)
}
}
var fn1=foo.fn
f1() // window
fn 函数在 foo 对象中作为方法被引
用,但是在赋值给 fn1 之后,fn1 的执行仍然是在 window 的全局环境中。因
此输出 window
const foo = {
bar: 10,
fn: function() {
console.log(this)
console.log(this.bar)
}
}
foo.fn()
将会输出{bar:10,fn:f} 10
这个时候this指向的是最后调用他的对象,foo.fn()语句中this指向foo对象
结论:在执行函数时,如果函数中的this是被上一级的对象所调用,那么this指向的就是上一级的对象;否则指向全局环境。
const person = {
name: 'Lucas',
brother: {
name: 'Mike',
fn: function() {
return this.name
}
}
}
console.log(person.brother.fn()) //Mike
this 指向最后调用它的对象
const o1 = {
text: 'o1',
fn: function () {
return this.text
},
}
const o2 = {
text: 'o2',
fn: function () {
return o1.fn()
},
}
const o3 = {
text: 'o3',
fn: function () {
var fn = o1.fn
return fn()
},
}
console.log(o1.fn()) //O1
console.log(o2.fn()) //O1
console.log(o3.fn()) //undefined
bind/call/apply 改变this指向
call/apply直接进行相关函数调用
bind不会执行相关函数,而是返回一个新的函数,这个新的函数自动绑定了新的this指向,开发者手动调用即可。
const target={}
fn.call(target,'arg1','arg2')
fn.apply(target,['arg1','arg2'])
fn.bind(target,'arg1','arg2')()
构造函数和this
function Foo() {
this.user = 'Lucas'
const o = {}
return o
}
const instance = new Foo()
console.log(instance.user)
将会输出 undefined,此时 instance 是返回的空对象 o
function Foo(){
this.user = "Lucas"
return 1
}
const instance = new Foo()
console.log(instance.user)
将会输出 Lucas,也就是说此时 instance 是返回的⽬标对象实例 this。
结论:如果构造函数中显式返回⼀个值,且返回的是⼀个对象,那么 this 就指
向这个返回的对象;如果返回的不是⼀个对象,那么 this 仍然指向实例。
this优先级相关
我们常把call、apply、bind、new对this绑定的情况称为显示绑定;根据调用关系确定的this指向称为隐式绑定。