一句话理解javascript的this指向
Posted 李星儒の博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一句话理解javascript的this指向相关的知识,希望对你有一定的参考价值。
js中的this指向,总是一个让人困扰的问题,其实this的指向问题只需要理解这句话:this总是指向当前函数的所有者(调用者),可能说完这句话,很多人都是各种不认同,肯定有人说构造函数this指向实例,call(),new都可以改变this的指向。其实call或者new都是遵循这句话的,只是他们各自都隐藏了他们的执行过程而已。甚至有人说,在闭包中,this的指向会很奇怪,感觉在闭包中this就是居无定所般的存在。
那么我们开始分析this的指向把:
var name = \'the window\';
function get_name(){
console.log(this.name);
}
get_name();
window.get_name();
上面的代码,首先定义了window的name属性为‘the window’,还定义了函数get_name,函数打印this.name。此时都是window调用get_name。一句话:this总是指向当前函数的所有者(调用者)
代码继续往下走:
var name = \'the window\';
function get_name(){
console.log(this.name);
}
get_name();
window.get_name();// the window
var obj = {
name:\'the obj\'
}
obj.fn_name = get_name;
obj.fn_name();// the obj
定义了一个新的obj对象,这个对象拥有name属性,并且值是‘the obj’,对象的动态特性,给obj添加了一个fn_namede 方法,并且这个方法也获得了get_name函数的指针:通过obj调用了fn_name所以打印出的结果是the obj;
3继续看添加的代码3:
//1
var name = \'the window\';
function get_name(){
console.log(this.name);
}
get_name();
window.get_name();// the window
// 2
var obj = {
name:\'the obj\'
}
obj.fn_name = get_name;
obj.fn_name();// the obj
// 3
var person = {
name:\'张飞龙\'
}
get_name.call(person); // 张飞龙
obj.fn_name.call(person);// 张飞龙
第3部分第代码,从新定义了一个person对象,这个对象的name属性为‘张飞龙’,他并没有什么方法,但是我们通过call调用了get_name函数和obj.fn_name方法。其实这个两个函数都是同一个函数,并且都是通过person调用的,所以都打印张飞龙。
再来看看再构造函数中的this;
function Person(){
this.name = \'雷锋\';
console.log(this)
this.say_name = function(){
console.log(this.name)
}
}
// 1
Person();//window对象
console.log(window.name);//雷锋
window.say_name()//雷锋
在还没有使用new的时候Person就是一个普通的函数。其实这和上面是一样的。
虽然是构造函数,其实在我眼里他还是个普通函数一样,只是new关键字的作用比较隐秘,发生的事情没有给我们看到而已
function Person(){
this.name = \'雷锋\';
console.log(this)
this.say_name = function(){
console.log(this.name)
}
}
var person1 = new Person();//person1
console.log(person1);//person1
person1.say_name();// 雷锋
这个时候我们看到打印台的结果,会认为第一个打印的person1和第二个打印的person1不是同一个,其实是同一个,只是第一个打印是Person内部的console.log(this),而执行这一句的时候,下面的这句this.say_name并未执行,此时的this(new 出来的)并没有来得及添加say_name方法,我还是那么一相情愿的认为这个Person函数实例化对象时,是因为实例对象调用了Person函数,this才指向实例对象的,并且new关键字确实在他内部隐藏了以下的四部操作
// var person ={};
// person.__proto__ = Person.prototype;
// Person.call(person);
// return person;
所以归结到底还是那句话。this的指向就是当前函数的调用对象。
最后我们再探讨以下闭包中的this;
var age = 24;
var person = {
age:34,
get_age:function(){
return function(){
return this.age;
};
}
};
var get_age1 = person.get_age()// get_age1的指针指向闭包中的匿名函数
console.log(get_age1());// 24 相当于window.匿名函数
我们只需要看this的函数的调用者是谁,接下来的这一句迷惑性就比较大了。
var person = {
age:34,
get_age:function(){
return function(){
return this.age;
};
}
};
var get_age1 = person.get_age()// get_age1的指针指向闭包中的匿名函数
console.log(get_age1());// 24 相当于window.匿名函数
console.log(person.get_age()())//这一大坨其实还只是得到了匿名函数
一眼看去最后一句的person.get_age()()这一句好像是在对象对函数的调用,其实这么调用返回的其实还是只是那个匿名函数。还是相当于window.匿名函数。因为person.get_age()它返回的其实仅仅是匿名函数,再来一个小括号就是匿名函数调用。如果这里还没明白的话,我继续往下写:
var age = 24;
var person = {
age:34,
get_age:function(){
return function(){
return this.age;
};
}
};
var get_age1 = person.get_age()// get_age1的指针指向闭包中的匿名函数
console.log(get_age1());// 24 相当于window.匿名函数
console.log(person.get_age()())//这一大坨其实还只是得到了匿名函数
var new_person = {
age:44
}
new_person.get_a = person.get_age()//new_person.get_a就是那个匿名函数
console.log(new_person.get_a())//这里的调用才是真真的对象调用方法,或者说此时的this才是new_person的调用人
最后两句无非就是把匿名函数拿到手,并且给这个新person的方法赋值,回到最开始说的一句话,this指向当前函数的调用者。
原文链接:https://blog.csdn.net/feilzhang/article/details/80576532
以上是关于一句话理解javascript的this指向的主要内容,如果未能解决你的问题,请参考以下文章