this的指向
全局作用域下this的指向
console.log(this)//this指向window
方法体中this的指向
普通函数this的指向
function demo1(){
console.log(this)
}
const obj = {
name:'demo2',
fn: function(){
console.log(this)
}
}
demo1()//this指向window
obj.fn()//this指向obj

箭头函数this的指向
const demo1 = () =>{
console.log(this)
}
const obj = {
name:'demo2',
fn: () => {
console.log(this)
}
}
demo1()//this指向window
obj.fn()//this指向window
定时任务中this的指向
setTimeout(function(){
console.log(this)//this指向window
},1000)
setTimeout(()=>{
console.log(this)//this指向window
})
可以看出,定时任务当中的this都是指向window的,这里也是有一定缘由的,因为定时任务都是由浏览器调用的,所以他指向的都是window对象
数组中this的指向
let arr = [1,2,3,4,5]
arr.forEach(function(item,index){
console.log(item,index,"this的指向:",this)
})

触发方法中this的指向
普通函数this的指向
let demo = document.getElementById('demo')
demo.onclick = function(){
console.log(this)//this指向dom元素
}

箭头函数this的指向
let demo = document.getElementById('demo')
demo.onclick = () =>{
console.log(this)//this指向window
}

this指向的修改/绑定
显示绑定:call、apply、bind
有3种修改this指向的方式:call、apply、bind,具体方法可见我的另一篇文章:http://t.csdn.cn/MR07e
这里有一个小插曲,有时候我们会见到,demo.call(this,xx) / demo.apply(this, [xx]) / demo.bind(this)
这么些写法,其中this的指向令人疑惑,如下方代码
function Person(name){
this.name = name
this.getName = function(){
return this.name
}
}
Person.prototype.getInfo = function(){
console.log('mvc')
}
function man(age,name){
this.age = age
Person.call(this,name) //this的指向?
}
let manObj = new man()
以上是一个JS继承的一种方式,我们称作借用构造函数实现继承,在子类当中借用父类构造方法,利用call/apply/bind方式修改this指向子类构造方法,从而生成子类实例时继承父类属性和方法,如果有听不懂的同学,这块先不着急理解,后续我会出一篇JS继承的文章
在上面的man方法中,有这么一个写法Person.call(this,name),请问this指向是什么?
按照我们上面的说法,man是一个全局方法,如果我们直接调用man()方法,那么this会指向window
但,这里引出一个新的知识!
new方式绑定this
function demo(name){
this.name = name
console.log(this)//demo{name:666}
}
let demoObj = new demo(666)

当我们new一个对象的时候,此时构造方法的this指向实例对象,如上图,因此上面man实际上在生成子类实例时才会调用到,因此man当中的Person.call(this),this实际上会指向子类实例,而不指向window,因为我们不是直接调用man()方法,而是利用new方式绑定this
隐式绑定(默认绑定)
实际上隐式绑定就是我们声明函数、对象时,存在于其中的this,指向对象或window
this绑定的优先级
new方式绑定 > 显示绑定 > 隐式绑定