• 关于js中this指向的问题


    this的绑定规则有4种

    1. 默认绑定
    2. 隐性绑定
    3. 显性绑定
    4. new绑定

    this绑定优先级

    new 绑定 > 显性绑定 > 隐性绑定 > 默认绑定

    1.如果函数被new 修饰

    this绑定的是新创建的对象,例:var bar = new foo(); 函数 foo 中的 this 就是一个叫foo的新创建的对象 , 然后将这个对象赋给bar , 这样的绑定方式叫 new绑定 .

    2.如果函数是使用call,apply,bind来调用的

    this绑定的是 call,apply,bind 的第一个参数.例: foo.call(obj); , foo 中的 this 就是 obj , 这样的绑定方式叫 显性绑定 .

    3.如果函数是在某个 上下文对象 下被调用

    this绑定的是那个上下文对象,例 : var obj = { foo : foo }; obj.foo(); foo 中的 this 就是 obj . 这样的绑定方式叫 隐性绑定 .

    4.如果都不是,即使用默认绑定

    例:function foo(){...} foo() ,foo 中的 this 就是 window.(严格模式下默认绑定到undefined).这样的绑定方式叫 默认绑定 .

    例:function foo(){...} foo() ,foo 中的 this 就是 window.(严格模式下默认绑定到undefined).这样的绑定方式叫 默认绑定 .

    其实除了默认绑定容易出现理解问题,其他3中都还好,下面来看下默认绑定的一些情况。
    重点是要理解:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

    var length = 10
    var obj = {
        length: 5,
        method: function(){
            console.log(this.length)
        }
    }
    obj.method()
    // 这种情况很简单,没啥问题,输出5
    
    var length = 10;
    function fn() {console.log(this.length)}
    
    var obj = {
        length: 5,
        method: function(fn){
            fn();
            arguments[0]();
        }
    }
    
    obj.method(fn);
    obj.method(fn,123)
    // 输出:
    // 10
    // 1
    // 10
    // 2
    

    上面这道题比较坑的是 length是JavaScript内置的属性。
    通过传参进去,调用的时候,调用它的对象是window。
    通过arguments0调用的时候,调用fn的对象是arguments,输出的是arguments的内置属性length

    情况1:如果一个函数中有this,但是它没有被上一级的对象所调用,那么this指向的就是window,这里需要说明的是在js的严格版中this指向的不是window,但是我们这里不探讨严格版的问题,你想了解可以自行上网查找。

    情况2:如果一个函数中有this,这个函数有被上一级的对象所调用,那么this指向的就是上一级的对象。

    情况3:如果一个函数中有this,这个函数中包含多个对象,尽管这个函数是被最外层的对象所调用,this指向的也只是它上一级的对象。

    var o = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a); //12
            }
        }
    }
    o.b.fn();
    
    var o = {
        a:10,
        b:{
            // a:12,
            fn:function(){
                console.log(this.a); //undefined
            }
        }
    }
    o.b.fn();
    
    var o = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a); //undefined
                console.log(this); //window
            }
        }
    }
    var j = o.b.fn;
    j();
    

    https://www.cnblogs.com/pssp/p/5216085.html

    var value = 1;
    
    var foo = {
      value: 2,
      bar: function () {
        return this.value;
      }
    }
    console.log((false || foo.bar)())
    

    逻辑运算符通常用于布尔型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&& 和 || 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。
    所以,相当于foo.bar 赋值给了一个变量,然后再调用

  • 相关阅读:
    对JAVA集合进行遍历删除时务必要用迭代器
    设计模式之单例模式(线程安全)
    List、Set、Map 和 Queue 之间的区别
    HashMap和Hashtable的区别
    Java WeakReference的理解与使用
    Java 理论与实践: 正确使用 Volatile 变量
    java中volatile关键字的含义
    最近5年183个Java面试问题列表及答案[最全]
    淘宝一月上钻是这样操作的
    Revit API找到风管穿过的墙(当前文档和链接文档)
  • 原文地址:https://www.cnblogs.com/fazero/p/11434687.html
Copyright © 2020-2023  润新知