普通函数情况下:如果是一个对象里的方法,则this指向当前对象,如果只是一个普通函数,则this指向全局window
定义在对象中的函数通常叫做方法 如:a:{ show:function(){} },像这样的 a=function(){} 我们叫他函数
console.log(this) //windows
function a() {
console.log(this) //windows
}
var test = {
name: 'test',
showName: function () {
console.log(this) // 当前对象:{name: 'test', showName: ƒ}
console.log(this.name) //test
},
}
test.showName()
再来看一种特例:
可以看到 showName方法是对象中定义的一个方法,所以this指向当前对象
showName2是在方法中定义的一个普通函数,所以this指向window
var test = {
name: 'test',
showName: function () {
console.log(this) // 当前对象:{name: 'test', showName: ƒ}
console.log(this.name) //test
//当前方法中再嵌套一层方法
function showName2() {
console.log(this) //window
console.log(this.name) //undefined
}
showName2()
},
}
test.showName()
箭头函数情况下:
1.箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时所处的对象(宿主对象),此处指父级作用域,而不是执行时的对象, 定义它的时候,可能环境是window
2.箭头函数中,this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。
map方法中我们用的是箭头函数,它本身没有this,所以向外找,外层是append方法,他是一个定义在对象中的普通方法,他的this指向对象本身,所以这个例子中的箭头函数this指向对象本身。
let arr = ['java','js','php','python']
let obj = {
name:'learn ',
append: function (Array) {
Array.map((e)=>{
console.log(this) // {name: 'learn ', append: ƒ} 对象本身
console.log(this.name + e)
})
}
}
obj.append(arr)
// 输出结果:
// learn java
// learn js
// learn php
// learn python
3.在字面量中直接定义的箭头函数无法继承该对象的this,而是往外再找一层,就找到了window,因为字面量对象无法形成自己的一层作用域,但是构造函数可以。
箭头函数中的this向上找的是父类作用域,而不是父类对象。js中只有三种作用域:块级作用域,函数作用域,全局作用域。
上面例子中 append是个方法 他有函数作用域 所以找得到他的this,而下面这个例子中字面量本身是没有作用域的,所以此时的this指向window
let a = {
show:()=>{
console.log(this)
}
}
a.show() //window