javascript中this指向问题

js中this指向问题

js中this指向问题老生常谈的问题了,在这里说一下我所理解的层面的this。

this 指的是当前对象,如果在全局范围内使用this,则指代当前页面window;如果在函数中使用this,则this指代什么是根据当前函数是在什么对象上调用。我们可以使用call和apply改变函数中this的具体指向。

console.log(this === window)  // true
console.log(window.alert === this.alert)  // true
console.log(this.parseInt("021",10))  // 21
//parseInt(string,radix); 
// 当只使用一个参数时,我们都知道是将其转为整数;
// radix 取值为 2~36,表示当前数是几进制,并将这个数转成十进制,当不在这个范围时,会输出NaN;                   
函数中的this是在运行时候决定的,而不是函数定义时。
    function foo(){
            console.log(this.fruit);
    }
    // 定义一个全局变量,等同于window.fruit = "banana";
    var fruit = "banana";
    // 此时函数中的this指向window;
    foo();  //   "banana"
    
    var  o = {
          fruit : "apple",
          foo : foo    
    };
    // 此时函数中的this指向o
    o.foo();  // "apple"

 

全局函数apply和call可以用来改变this的指向,如下:

 

function foo(){
            console.log(this.fruit);
    }
    // 定义一个全局变量,等同于window.fruit = "banana";
    var fruit = "banana";

    var  o = {
          fruit : "apple"
    };
    
    foo.apply(window);  // "banana";
    foo.call(o);  // "apple";

 

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

因为在JavaScript中,函数也是对象,我们看下面这个例子:

function foo(){
          if(this === window){
            console.log("this is window");
         }   
    };
    // 函数foo也是对象,可以为对象定义属性,然后属性为函数
     foo.boo = function(){
        if(this === foo){
              console.log("this is foo");       
         }else if(this === window){
                console.log("this is window");
            }
     };
    
     // 等价于 window.foo();
     foo();  // "this is window";
     // 可以看到函数中this的指向调用函数的对象
     foo.boo();  // "this is foo";
    // 可以使用call改变函数中this指向
    foo.boo.call(window); // "this is window";

对象中的嵌套函数的this指向不是当前对象,而是window,看如下例子:

 var name = "window.name";
      var obj = {
          name : "obj.name",
          getName:function(){
              console.log(this.name);
              return function(){
                  console.log(this.name);
              } 
          }
      }
      obj.getName()();  // "obj.name"  "window.name"

同样是obj调用的getName和getName里面的方法,结果却是不同的值,这就说明嵌套函数中的this已经不指向当前对象了,而指向window。

那么,我们要怎样解决上述问题呢?主要有三种解决办法,如下:

1.使用函数的bind方法,绑定当前this;

 var name = "window.name";
     var obj = {
         name : "obj.name",
          getName:function(){
             console.log(this.name);
               return function(){
                  console.log(this.name);
              }.bind(this);
          }
      };
      obj.getName()();  //  "obj.name"  "obj.name"

2.使用变量将上面的this接收一下,然后下面不使用this,使用那个变量;

var name = "window.name";
       var that = null;
      var obj = {
           name : "obj.name",
           getName:function(){
              that = this;
              console.log(this.name);
               return function(){
                  console.log(that.name);
              }
          }
       }
      obj.getName()();  //  "obj.name"    "obj.name"

 

3.使用ES6的箭头函数,可以完美避免此问题;

 var name = "window.name";
      var obj = {
          name : "obj.name",
         getName:function(){
              console.log(this.name);
              return () => {
                  console.log(this.name);
              }
          }
      }
      obj.getName()();    //  "obj.name"    "obj.name"

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值