如何判断this指向
口诀:一般来说就是谁调用它,this就指向谁
1.普通函数(this指向window)
var age=18;
function fn(){
console.log(this);
}
fn()//Window {window: Window, self: Window, document: document, name: '', location: Location, …}
按照口诀fn()等于window.fn(),所以this指向window
2.箭头函数
var age=19;
var arrow=()=>{
var age=20;
console.log(this.age);
}
arrow()//19
箭头函数的this取决于其父级作用域,没有的话就是全局也就是window
3.对象函数(this指向该方法所属对象)
一层对象中的普通函数
var name='张三'
var obj={
name:"李四",
say:function (){
console.log(this.name);
}
}
obj.say()//李四
/************************/
一层对象中的普通函数,obj调用了say(),所以this指向了obj
一层对象中的箭头函数
var name='张三'
var obj={
name:"李四",
say:()=>{
console.log(this.name);
}
}
obj.say()//张三
一层对象中的箭头函数,箭头函数的this指向取决于父级作用域,父级这里是对象,对象没有作用域且现在是位于全局,所以继续向上找,找到全局
两层对象中的普通函数
var name='张三'
var obj={
name:"李四",
say:function (){
console.log(this.name);
},
secondObj:{
name:"王五",
say:function (){
console.log(this.name);
}
}
}
obj.say();//李四
obj.secondObj.say()//王五
和一层的普通函数一样谁调用就指向谁
两层对象中的箭头函数
var name = '张三'
var obj = {
name: "李四",
say: () => {
console.log(this.name);
},
secondObj: {
name: "王五",
say: () => {
console.log(this.name);
}
}
}
obj.say();//张三
obj.secondObj.say()//张三
同理和一次函数对象的箭头函数相同,箭头函数的this取决于父级作用域,父级是对象没有继续往上延升,最后就找到了全局
对象里的方法返回普通方法
var age=18;
var obj={
age:"19",
say:function (){
return function (){
console.log(this.age);
}
}
}
obj.say()//ƒ (){console.log(this.age);}
obj.say()();//18
obj.say()执行后返回一个方法,所以再加一个()会执行,执行的时候这个方法相当于被全局调用,所以这个this指向全局。但本质上从对象中返回方法,目的就是使用对象中的属性。
var age=18;
var obj={
age:"19",
say:function (){
var that=this
return function (){
console.log(that.age);
}
}
}
obj.say()//ƒ (){console.log(that.age);}
obj.say()();//19
在函数返回之前,我们通过that获取到指向obj的这个this,所以结果是这里的19
对象里的方法返回箭头方法
var age=18;
var obj={
age:"19",
say:function (){
return ()=>{
console.log(this.age);
}
}
}
obj.say()//ƒ (){console.log(this.age);}
obj.say()();//19
箭头函数的this指向父级作用域,这里箭头函数的父级是function,function会形成作用域,这里function作用域中的this指向obj,所以箭头函数指向了obj
4.构造函数
普通构造函数
function Person(name,age){
this.name=name;
this.age=age
}
var zs=new Person('张三',18)
console.log(zs);//Person {name: '张三', age: 18}
/*********************/
function Person(name,age){
this.name=name;
this.age=age;
var obj={
age:10
}
return obj
}
var zs=new Person('张三',18)
console.log(zs);//{age: 10}
构造函数在没有return的情况下,this指向实例化的对象,有return,则指向返回的那个对象
构造函数里的方法
var name = '张三'
function Person() {
this.name = '李四';
this.commonFn = function () {
console.log(this);
}
this.arrowFn = () => {
console.log(this);
}
}
var number = new Person()
number.commonFn();//Person {name: '李四', commonFn: ƒ, arrowFn: ƒ}
number.arrowFn()//Person {name: '李四', commonFn: ƒ, arrowFn: ƒ}
构造函数里的普通方法this指向构造函数new后的实例,箭头函数还是寻找父级作用域,父级是Person(),方法是有自己的作用域的,所以箭头函数指向Person