this四大绑定
- 默认绑定
function foo(){
console.log(this)
}
foo() //输出windows
- 隐式绑定
var obj={
name:"obj",
foo:function(){
console.log(this.name)
}
}
obj.foo() //输出obj
- 显示绑定
//call apply bind
function foo(){
console.log(this)
}
foo.call("abc") //输出"abc"
- new绑定
function foo(a) {
this.a = a;
}
var bar = new foo( 2 );
console.log( bar.a ); // 2
优先级顺序:new绑定>显示绑定(apply/call/bind)>隐式绑定(obj.foo()) >默认绑定
- 忽略显示绑定
funciton foo(){
console.log("foo")
}
foo.apply(null) //指向windows
foo.call(undefined) //指向windows
- 箭头函数的this获取 寻找上层作用域 显示绑定不生效
var name = "window"
function Person(name){
this.name = name;
this.foo2 = function(){
return ()=>{
console.log(this.name) //this.name指向的是foo2的作用域的this
}
}
}
var person1 = new Person("person1")
var person2 = new Person("person2")
person1.foo2()() //person1
person1.foo2.call(person2)()//person2 作用域已更改为person2
this绑定的分析图
🚧🚧:分析几道面试题
- 字面量对象
var name = 'window'
var person1 = {
name: 'person1',
foo1: function () {
console.log(this.name)
},
foo2: () => console.log(this.name),
foo3: function () {
return function () {
console.log(this.name)
}
},
foo4: function () {
return () => {
console.log(this.name)
}
}
}
var person2 = { name: 'person2' }
person1.foo1()//foo1被person1显式调用,输出person1
person1.foo1.call(person2)//foo1被persopn2改变this指向,输出person2
person1.foo2()//箭头函数看上层作用域,为全局作用域,输出window
person1.foo2.call(person2)//call函数无效,输出window
person1.foo3()()//person1.foo3()得到内部function,之后被全局调用,输出window
person1.foo3.call(person2)()//改变foo3的this不影响被全局调用,输出window
person1.foo3().call(person2)//内部funciton被person2对象call调用,输出person2
person1.foo4()()//箭头函数看上层作用域,即foo4函数,foo4被person1调用,输出person1
person1.foo4.call(person2)()//foo4函数被call改变指向,输出person2
person1.foo4().call(person2)//还是看上层作用域foo4,输出persopn1
- 构造函数
var name = 'window'
function Person (name) {
this.name = name
this.foo1 = function () {
console.log(this.name)
},
this.foo2 = () => console.log(this.name),
this.foo3 = function () {
return function () {
console.log(this.name)
}
},
this.foo4 = function () {
return () => {
console.log(this.name)
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.foo1()//显示绑定,输出person1
person1.foo1.call(person2)//被call调用,输出person2
person1.foo2()//箭头函数看上层作用域,为person1,输出person1
person1.foo2.call(person2)//call不改变作用域,输出person1
person1.foo3()()//person1.foo3()得到内部function,进行全局调用,输出window
person1.foo3.call(person2)()//同上全局调用,输出window
person1.foo3().call(person2)//得到内部function后被call调用,输出person2
person1.foo4()()//箭头函数看上层作用域,为foo4函数被person1调用,输出person1
person1.foo4.call(person2)()//foo4函数被call指向person2,输出person2
person1.foo4().call(person2)//此时call不影响foo4的作用域,输出person1
- 构造函数2
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj',
foo1: function () {
return function () {
console.log(this.name)
}
},
foo2: function () {
return () => {
console.log(this.name)
}
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.obj.foo1()()//person1.obj.foo1()得到内部function,被window调用,输出window
person1.obj.foo1.call(person2)()//foo1被call改变指向了,但是内部function还是被window调用,输出window
person1.obj.foo1().call(person2)//得到内部funtion后call调用,指向person2,输出person2
person1.obj.foo2()()//箭头函数看上层作用域foo2,foo2被obj调用,输出obj
person1.obj.foo2.call(person2)()//foo2被call改变指向了,输出person2
person1.obj.foo2().call(person2)//没有改变foo2的指向,依然输出obj