今天阅读了coderwhy老师关于this指向的文章,为了让自己的对this这方面的知识点加深印象,用自己语言复述相关的知识点
一、指向window的情况
- 直接函数调用,既最后是通过函数调用的情况
//情况一
function foo(){
console.log(this) //window
}
//情况二
function info(Fn){
Fn()
}
const obj = {
bar:function(){
console.log(this) //window
}
}
info(obj.bar)
//情况三
function foo(){
console.log(this) //window
}
const obj1 = {
name:"obj1",
foo:foo
}
const bar = obj1.foo //将obj1中的foo函数赋值给bar
bar()
二、绑定的类型(绑定规则)
隐式绑定、显示绑定、new绑定、内置函数
1、 隐式绑定
隐式绑定一般都是通过对象发起调用函数
//情况一
function foo(){
console.log(this) //obj
}
const obj = {
foo:foo
}
obj.foo()
//情况二
function foo(){
console.log(this) //obj1
}
const obj1 = {
foo:foo
}
const obj2 = {
obj1:obj1
}
obj2.obj1.foo()
2、显示绑定
通过apply,call,bind绑定指定的对象
function foo(){
console.log()
}
foo.call(window) //window
foo.call({name:"xhz"}) //{name:"xhz"}
foo.call(123)// Number对象,存放是123
3、new绑定
使用new关键字来调用函数时,会执行以下操作:
- 创建一个全新的对象
- 这个新对象会被执行Prototype连接
- 这个新对象会绑定到函数调用的this上(此时this被绑定)
- 如果函数没有返回其他对象,表达式会返回这个新对象
function Animal(name){
console.log(this)//Animal{}
this.name = name //Animal{name:"Fish"}
}
const fish = new Animal("Fish")
console.log(fish)
4、内置函数
- setTimeout
setTimeout内部通过apply进行this对象绑定,并且绑定的是全局对象
setTimeout(function(){
console.log(this) //window
},1000)
- 数据的forEach
在forEach中传入的函数是自动调用函数(默认调用)
var names = ["abc","cba","nba"]
names.forEach(function(item){
console.log(this) //window
})
//当然也可以指定对象
var names = ["abc","cba","nba"]
var obj = {name:"xhz"}
names.forEach(function(item){
console.log(this) //window
},obj)
四个规则优先级
new > 显示绑定 > 隐式绑定 > 默认绑定
三、规则之外
1.忽略显示绑定
如果我们传入一个null或者undefine,那么这个显示绑定会被忽略,使用默认规则
function foo(){
console.log(this)
}
var obj = {
name:"xhz"
}
foo.call(obj) //this -> obj
foo.call(null) //this -> window
foo.call(undefine) //this -> window
var info = foo.bind(null)
info() //this -> window
2.间接函数引用
function foo(){
console.log(this)
}
obj1 = {
foo:foo
}
obj2 = {
name:"obj2"
}
obj1.foo() //obj1
(obj2.foo = obj1.foo)() //window
3.ES6箭头函数
箭头函数不绑定this对象,它会从上层作用域中找到对应的this
//情况一
var obj = {
getData: function(){
setTimeout(()=>{
console.log(this)
},1000)
}
}
obj.getData() //this -> obj
//情况二
var obj = {
getData: ()=>{
setTimeout(()=>{
console.log(this)
},1000)
}
}
obj.getData() //this -> window