说到this 的指向首先要搞明白以下两点
1. 函数被调用时才会确定该函数内的this指向,因为在函数中this和arguments是两个特殊的变量(只有在函数被调用时才会存在且只存在活动对象范围)
2. 要确定函数中this 的指向,必须先找到该函数被调用的位置, 以下函数几种应应用场景下的this 指向
作为对象属性被调用
var ken = 'fatty'
function test () {
console.log(this.ken)
}
var obj = {
ken = 'handsome man',
test
}
obj.test() //'handsome man'
var ken = 'fatty'
function test () {
console.log(this.ken)
}
var obj = {
ken: 'handsone man',
test
}
var obj1 = {
ken: 'pig',
obj
}
obj1.obj.test() // 'handsome man'
var ken = 'cat'
function test () {
console.log(this.ken)
}
var obj = {
ken = 'handsome man'
}
setTimeout(obj.test) // 'cat'
/*
setTimeout(obj.test)相当于
function setTimeout (test, time) {
// 等time走完
test()
}
*/
谁调用这个函数(直接调用者,即直属上司:在第二段code中直属上司为obj),this就指向谁,在setTimeout和setInterval中this指向为上级this的指向
作为普通函数被调用
var ken = 'fatty'
function test () {
console.log(this.ken)
}
test() //'fatty'
在此场景中 this会指向全局对象,因为没有其他影响去改变this,this 默认指向全局对象(浏览器是window,node中是global),在严格模式下this为undefined
作为构造函数被调用
var ken = 'handsome man'
function test (ken) {
this.ken = ken
}
var rich = new test ('pig')
console.log(rich.ken) //'pig'
new这个操作符其实是new了一个新对象出来,而被new的test我们称为构造函数,我们可以在这个构造函数里定义一下将要到来的新对象的一些属性。那么在构造函数里,我们怎样去描述这个还未出生的新对象呢?没错,就是用this。所以构造函数里的this指的就是将要被new出来的新对象。
call,bind和apply的应用
var ken = 'dog'
function test () {
console.log(this.ken)
}
var obj = {
ken = 'cat',
test
}
var test1 = obj.test
test1.call(obj) // 'cat'
可以看到,我们通过call(apply跟call的区别只是传参,作用是一样的,bind有点区别,bind能让我们的函数延迟执行,apply与call调用就执行,所以bind这样的形式我们也称为函数柯里化,这些就不是我们这里要说的啦)来调用testCopy,并且传入了你想要this指向的上下文,那么this就会乖乖按照你的指示行事啦。看到这里,我们也可以想象第一、二种形式其实可以转化成call/apply的形式
箭头函数
var ken = 'cat'
var test = () => {
console.log(this.ken)
}
var obj = {
ken = 'pig',
test
}
obj.test() // 'cat'
函数被调用时才会确定函数内的this指向但不包括箭头函数,箭头函数中的this在函数定义的时候就已经确定,它指向为上级作用域this的指向 关于跨域代码规范