this那些事儿

104 阅读2分钟

一般地,

  • this是个对象;
  • 在函数中使用;
  • 可用apply、call、bind改变this的指向,null、undefined除外;
  • 函数也是个对象
  • “谁调用的函数,函数中的this就指向谁”
  • 优先级:new fn() > 显示绑定(bind、call、apply) > 隐式绑定obj.fn() > 默认绑定fn()
  • 箭头函数中的this指向父级作用域的this

<script>
function lxx(){
  console.log(this);
}

lxx()
</script>

以上代码,相当于在全局环境中定义了个函数,并且调用了函数。换个说法就是,给全局环境中的window对象上定义了个属性lxx,该属性的值是一个函数,调用时相当于window.lxx()。此时window调用了lxx函数,则this指向window


<script>
var person = {
    name: 'lxx',
    eat: function(){
       console.log(this); 
    }
}

person.eat()
</script>

以上代码,person调用的eat函数,则eat函数中的this指向person


<script>
var person = {
    name: 'lxx',
    eat: function(){
       console.log(this); 
    }
}

var fn = person.eat
fn()
</script>

以上代码,将person对象的eat函数赋值给了fn,然后调用fn函数,相当于window.fn(),此时window调用的eat函数,则eat函数中的thiswindow


<script>
function lxx(){
  console.log(this);
}
lxx.call('aaa') // 将this指向字符串aaa对象
lxx.apply('bbb') // 将this指向字符串bbb对象
</script>

以上代码,通过call、apply两个函数调用lxx函数,并修改函数中的this指向。


<script>
function lxx(num1, num2){
  console.log(num1 + num2, this);
}
lxx.call('aaa', 1, 2) // 参数依次传入
lxx.apply('bbb', [1, 2]) // 参数放到数组中
</script>

以上代码,展示了call、apply两种方式传参的区别。


<script>
function lxx(){
  console.log(this);
}
var fn = lxx.bind('aaa')
fn()
</script>

以上代码,使用bind改变了this指向,bind方法可以修改this指向,返回值为一个新的函数,该函数是一个已经绑定了this指向的函数,此时,再调用该函数fn,函数中的this则指向绑定的字符串aaa对象。


<script>
let oDiv = document.getElementById('app')

oDiv.onclick = function(){
  console.log(111, this);
}

oDiv.onclick = function(){
  console.log(222, this);
}
</script>

以上代码,给一个DOM元素绑定事件处理函数。oDiv是一个对象,onclick是对象上的一个属性,值为一个函数,可以理解成oDiv.onclick(),根据“谁调用指向谁”,此时,函数中的this指向oDiv。另外此种方式只可绑定一个事件处理函数,下边的会覆盖掉上边的。相当于给onclick属性赋值了一个新函数。


<script>
let oDiv = document.getElementById('app')

oDiv.addEventListener('click', function(){
  console.log(111, this);
})

oDiv.addEventListener('click', function(){
  console.log(222, this);
})
</script>

以上代码,是给DOM对象绑定事件处理函数的另一种方式,此种方式可以给一个DOM对象绑定多个事件处理函数,这里猜测:内部实现可能是收集绑定的多个函数,当调用函数时使用显示绑定(call等)的方法修改函数中的this指向fn.call(oDiv)


<script>
[1,2,3].forEach(function(item){
  console.log(item, this);
}, 'aaa')
</script>

以上代码,是数组的forEach方法,当迭代数组中的每一项时,独立执行回调函数,此时this的指向为window。也可以通过传递forEach的第二个参数来修改回调函数中的this指向,此时this的指向为字符串对象aaa