对JavaScript中this的理解
JavaScript中的this其实没传说中的那么难,也没那么乱。
我们来分析下,this主要是跟它的执行环境有关。
而通常情况下,this都是放在函数体中或可执行的JS代码中(函数体除外)。
至于JS可执行代码中的this,用的不多,所以本文举例较少。
至于函数体中的this,我们只要弄清楚this所处的函数体是谁在调用,不就知道this是谁了吗?
注意:此文中的函数调用,是指该函数作为某对象的一个属性方法被执行,而不是单纯的在某个对象的作用域中执行就是调用
-------------------------------------------------------------------------------------------------------------
NO.1可执行代码中的this(包含在函数体中的this除外)
1. 全局代码中的this
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
alert(this)//window
2. HTML事件处理程序中的this
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<input type="button" name="click" id="click" value="clicked" onclick="console.log(this)" />
<!--
输出结果:<input type="button" name="click" id="click" value="clicked" onclick="console.log(this)">
-->
NO.2 若this所在的函数体没有被对象调用,则this指向window(默认调用对象是window)。无论这个函数在哪,也无论这个函数体嵌套了多少层。
示例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//第一层 function test1(){ console.log(this); //window //第二层 function test2(){ console.log(this); //window //第三层 function test3(){ console.log(this); //window //第四层 function test4(){ console.log(this); //window } test4(); } test3(); } test2(); } test1();
分类举例:
1. 作为单纯的函数调用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function test(){ console.log(this); //window } test();
2. 作为构造函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function person(name){ this.name = name; this.type = "person"; this.eat = function(){ alert("eat"); }; console.log(this); } person(); // window var person1 = new person("wlh"); //person1
函数内部的this指向新构建的对象,若没有,指向 window。
其实跟单纯的函数调用是一样的,只是有个一个高逼格的名称(构造函数)。(理解构造函数和普通函数的区别!)
3、对象函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var name = "clever coder"; var person = { name : "foocoder", hello : function(sth){ console.log(this.name + " says " + sth); } } person.hello("hello world"); // foocoder says hello world
this指向person对象,即当前对象。
此处的hello作为person的属性方法被执行,所以它的this指向了person
4、内部函数
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var name = "clever coder"; var person = { name : "foocoder", hello : function(sth){ function sayhello(sth) { console.log(this.name + " says " + sth); }; sayhello(sth); } } person.hello("hello world");//clever coder says hello world
在这个内部函数中,sayhello函数只是在person.hello的函数体内被执行。
但它并没有作为当前对象的属性方法被执行。所以这个内部函数仍然是属于没有对象调用,只是执行了。所以它内部的this指向 window
等弄清楚了this的指向问题,再来看call()、apply()、bind()改变后的this指向,不也是很明朗吗?
这三个函数只是单一的改变当前函数的this指向,不影响其他地方
-------------------------------------------------------------------------------------------------------------
测试看是否完全理解了
练习一,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var age = 19; function person(){ var age = 20; this.age = 21; } console.log(age); person(); console.log(age);
结果:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var age = 19; function person(){ var age = 20; // 若没有明确的调用对象(默认window调用),则此处的this相当于window,执行person()后,覆盖了全局变量age this.age = 21; } console.log(age); //19 person(); console.log(age); //21
练习二:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var person = { age:19 } function person1(){ var age = 20; this.age = 21; function person2(){ var age = 22; this.age = 23; } person2(); } console.log(person.age); person1.call(person); console.log(person.age); console.log(age);
结果:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
var person = { age:19 } function person1(){ var age = 20; this.age = 21; function person2(){ var age = 22; this.age = 23; } person2(); } //调用的是person对象的age属性的值 console.log(person.age); //19 //执行person1,并利用call将person1中的this指向person对象。所以 this.age = person.age = 21 person1.call(person); console.log(person.age); //21 //这个跟'练习一'一样,若没有明确指出调用对象,则this指向window console.log(age); //23
本文算是从另一个角度去重新理解了JavaScript中的this
这是之前转载博客:详解JavaScript中的this ,