zoukankan      html  css  js  c++  java
  • 浅谈js中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的指向,如下:(apply和call的唯一区别,就是在传参的时候,apply的参数需要放在一个数组里面,而call不需要)

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

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

    function foo(){
     2          if(this === window){
     3              console.log("this is window");
     4         }   
     5     };
     6     // 函数foo也是对象,可以为对象定义属性,然后属性为函数
     7     foo.boo = function(){
     8         if(this === foo){
     9              console.log("this is foo");       
    10         }else if(this === window){
    11                 console.log("this is window");
    12             }
    13     };
    14     
    15     // 等价于 window.foo();
    16     foo();  // "this is window";
    17     // 可以看到函数中this的指向调用函数的对象
    18     foo.boo();  // "this is foo";
    19     // 可以使用call改变函数中this指向
    20     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";
     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接收一下,然后下面不使用this,使用那个变量;

     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的箭头函数,可以完美避免此问题;

     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"
  • 相关阅读:
    前端面试题—Js
    前端面试题—css
    前端面试题—html
    JavaScript 闭包
    JavaScript 计算斐波那切数列
    JavaScript continue使用
    JavaScript break 使用
    JavaScript 综合运算 (数字运算符+比较运算符+逻辑运算符)
    JavaScript 逻辑运算符 特殊字符 纯数字字符串
    JavaScript 比较运算符 特殊字符 纯数字字符串
  • 原文地址:https://www.cnblogs.com/zhaosijia----1234/p/8973364.html
Copyright © 2011-2022 走看看