理解JS中this的指向

this 指代当前对象,若在全局内使用,则指代当前页面window;若在函数中使用,则依据当前函数被调用的对象而定,可初步理解为“谁调用就是谁”。

一、this的指向在函数定义时是无法确定的,只有函数执行时才能确定this到底指向谁。

 1   function demo() {
 2             console.log(this.fruit);
 3     }
 4     // 定义全局变量,等同于window.fruit = "banana";
 5     var fruit = "banana";
 6     // 此时函数中的this指向window;
 7     demo();  //   "banana"
 8     
 9     var  obj = {
10           fruit : "apple",
11           demo : demo    
12     };
13     // 此时函数中的this指向obj
14     obj.demo();  // "apple"

二、JS中函数也是对象,可定义属性

 1         function demo() {
 2              if(this === window){
 3                 console.log("this is window");
 4                }   
 5         };
 6         // 函数也是对象,可以为对象定义属性,值为函数
 7         demo.bar = function(){
 8             if(this === demo){
 9                  console.log("this is demo");       
10             }else if(this === window){
11                     console.log("this is window");
12                 }
13         };
14         
15         // 等价于 window.demo();
16         demo();  // "this is window";
17         // 函数中this指向调用函数的对象
18         demo.bar();  // "this is demo";
19         // 可以使用call改变函数中this指向
20         demo.bar.call(window); // "this is window";

三、对象中嵌套函数的this指向不是当前对象,而是window

 1         var name = "window.name";
 2         var obj = {
 3             name : "obj.name",
 4             getName:function(){
 5               console.log(this.name);
 6               return function(){ //return 返回一个函数,
 7                   console.log(this.name); 
 8             } 
 9           }
10         }
11         obj.getName()();  // "obj.name"  "window.name"

obj.getName()执行后返回一个函数,这个返回函数再次执行是被window对象调用的,因此前者this指向obj对象,后者指向window对象。可通过三种方式改变此this指向。

1、使用函数的bind方法

 1         var name = "window.name";
 2         var obj = {
 3             name : "obj.name",
 4             getName:function(){
 5               console.log(this.name);
 6               return function(){
 7                   console.log(this.name);
 8                 }.bind(this);
 9              }
10            };
11         obj.getName()();  //  "obj.name"  "obj.name"

2.使用变量接收上面的this,下面使用变量替代

 1         var name = "window.name";
 2         var that = null;
 3         var obj = {
 4             name : "obj.name",
 5             getName:function(){
 6                 that = this;
 7                 console.log(this.name);
 8                  return function(){
 9                     console.log(that.name);
10                 }
11             }
12         }
13         obj.getName()();  //  "obj.name"    "obj.name"

3.使用ES6的箭头函数

 1         var name = "window.name";
 2           var obj = {
 3             name : "obj.name",
 4               getName:function(){
 5               console.log(this.name);
 6               return () => {
 7                   console.log(this.name);
 8               }
 9           }
10           }
11          obj.getName()();    //  "obj.name"    "obj.name"

四、全局函数apply和call可以用来改变this的指向

apply和call的唯一区别,就是在传参的时候,apply的参数需要放在一个数组里面,而call不需要。

 1         function demo(){
 2             console.log(this.fruit);
 3         }
 4         // 定义一个全局变量,等同于window.fruit = "banana";
 5         var fruit = "banana";
 6 
 7         var  obj = {
 8             fruit : "apple"
 9         };
10         demo(); //相当于window.demo()和demo.apply(window);
11         demo.apply(window);  // "banana";
12         demo.call(obj);  // "apple";

猜你喜欢

转载自www.cnblogs.com/splendid/p/9719609.html