一、回答点
this的指向 优先级 特殊this指向 ...
this的绑定规则有哪几种? 默认绑定、隐式绑定、显式绑定、new绑定
默认绑定:独⽴函数调⽤,函数没有被绑定到某个对象上进⾏调⽤
隐式绑定:通过某个对象发起的函数调⽤,在调⽤对象内部有⼀个对函数的引⽤
显式绑定(apply/call/bind):明确this指向的对象,第⼀个参数相同并要求传⼊⼀个对象
new绑定:
1) 创建⼀个全新对象
2 ) 新对象被执⾏prototype链接
3 ) 新对象绑定到函数调⽤的this
4 ) 如果函数没有返回其他对象,表达式会返回这个对象
二、深入回答
this的优先级
new 绑定 > 显示绑定 > 隐式绑定 > 默认绑定
特殊this指向
1 ) 箭头函数:
箭头函数会根据其声明的地方来决定 this
const fo = { fn:function(){ setTimeout(function) { console.log(this) } } } console.log(fo.fn()) // window
this出现在定时器中的回调函数内,因此this指向window对象.如果需要this指向fo这个对象,可以用箭头函数
const fo = { fn:function() { settimeout(()=>{ console.log(this) }) } } console.log(fo.fn()) // {fn:f}
需要注意:箭头函数的this绑定是无法通过call apply bind方法修改.因为箭头函数没有构造函数constructor,所以也不可以使用new进行调用,不能作为构造函数.
2 ) 数组方法
在属性arr的forEach回调函数中的this 指向什么?
var obj = { arr:[1] } obj.arr.forEach(function(){ console.log(this) }) // forEach方法如下: Array.forEach(function(currentVal,index,arr),thisVal) // currentVal => 当前元素,必选 // index => 索引值,可选 // arr => 当前元素所属数组对象,可选 // thisVal => 传递给函数的值 一般用this值,如果为空 会把undefined传递给this值.
输出:全局对象
这里可以看出来,只传递了一个值,第二个值未传递,默认为undefined,所以输出 全局对象
除了forEach方法外,还有其他的方法函数需要传递,可以查看Mdn文档.
3 ) 立即执行函数
立即执行函数 => 定义后立即调用的函数 为 立即执行函数
var name = "coderhing" var obj = { name:"coder", sayHello:function(){ console.log(this.name) }, hello:function(){ (function(ch) { ch() })(this.sayHello) } } obj.hello() // 输出 coderhing
输出为coderhing,是window.name的值.立即执行函数是匿名函数,可以直接调用,而不是通过属性访问(obj.fn)的形式来给它指定一个对象,所以它的this是确定的,就是默认的全局对象window
4 ) 定时器
setTimeout和setInterval中函数的this指向规则是一样的
var name = "coderhing" var obj = { name:"coder", hello:function(){ setTimeout(function() { console.log(this.name) }) } } obj.hello() // 输出 coderhing
this.name是在obj.hello()被调用的,结果输出 window.name , 定时器 都是在全局作用域下实现的.
无论是setTimeout和setInterval里传入的函数,都会首先被交到全局对象手里.因此,函数中的this值 指向 window.