javascript高级语法之一 : this的指向(箭头函数)

javascript高级语法之一 : this的指向(箭头函数)

启示 : 

  1.函数在调用时,javascript会默认给this绑定一个值;

  2.this的绑定和定义的位置(编写的位置)没有关系;

  3.this的绑定和调用方式以及调用的位置有关系

  4.this时运行时被绑定的

 

绑定规则 :

  优先级 :

    默认绑定最低

    显式绑定   >  隐式绑定

    new绑定   >  隐式绑定

    new   >   bind  [  new不可以和apply/call 一起使用, 但是bind可以和new一起使用 ]

    bind  >   apply/call

    总结 : new  >  bind  > apply/call  > 隐式  >  默认

    

  绑定一 : 默认绑定

    普通函数被独立调用指向window 【 严格模式下,独立调用的函数指向undefined

 

  绑定二 : 隐式绑定

    如果函数它是被某一个对象来引用并且调用它, 那么this会指向这个对象(调用的那个调用)

 

  绑定三显示绑定 [ call - apply - bind(很少使用)]

    call  和  apply 方法 : 

      1.第一个参数是相同的,要求传入一个对象

        这个对象就是给this准备的,在调用这个函数时,会给this绑定到这个传入的对象上

      2.后面的参数 : call为参数列表  ,   apply 为数组

    bind 方法 :   会生成一个新的绑定函数,不用每次都call或者apply  

      1.第一个参数也是要传入一个对象      

      2.后面的参数 : 参数列表

 

  绑定四 : new绑定

    1.创建新对象

    2.将this指向这个空对象

    3.执行函数体中的代码

    4.没有显示返回非空对象时,默认返回这个对象

 

  内置函数的this

    定时器    ==>   window

    foreach   ==>   默认window , 第三个参数可以改变this的指向

    点击事件  ===>  元素本身

  

  特殊的[规则之外] : 

    1.如果在显示绑定中,我们传入一个null 或者 undefined , 那么这个显示绑定会被忽略 , 使用默认规则(window) 

    2.间接函数引用 

 

 

 

  绑定一 : 默认绑定 - 代码

    // 定义函数
    // 1.普通的函数被独立的调用 
    function foo() {
      console.log("foo:", this)
    }
    foo() //window


    // 2.函数定义在对象中, 但是独立调用
    var obj = {
      name: "why",
      bar: function() {
        console.log("bar:", this)
      }
    }

    var baz = obj.bar
    baz()  //windows


    // 3.高阶函数
    function test(fn) {
      fn()
    }

    test(obj.bar) //window

    // 4.严格模式下, 独立调用的函数中的this指向的是undefined
    // "use strict"

 

  绑定二 :隐式绑定 - 代码

    // 隐式绑定
    function foo() {
      console.log("foo函数:", this)
    }

    var obj = {
      bar: foo
    }

    obj.bar() // obj

  

  绑定四 : new绑定 - 代码  

    function foo() {
      this.name = "why"
      console.log("foo函数:", this)
    }

    new foo()  // foo

 

  绑定三 : 显示绑定[ apply - call ] - 代码

    // call/apply
    function foo(name, age, height) {
      console.log("foo函数被调用:", this)
      console.log("打印参数:", name, age, height)
    }

    // 普通()调用
    foo("why", 18, 1.88)

    // apply
    // 第一个参数: 绑定this
    // 第二个参数: 传入额外的实参, 以数组的形式
    foo.apply("apply", ["kobe", 30, 1.98])

    // call
    // 第一个参数: 绑定this
    // 参数列表: 后续的参数以多参数的形式传递, 会作为实参
    foo.call("call", "james", 25, 2.05)

  

  绑定三 :  显示绑定[ bind ] - 代码

    function foo(name, age, height, address) {
      console.log("foo:", this)
      console.log("参数:", name, age, height, address)
    }

    var obj = { name: "why" }

    // 需求: 调用foo时, 总是绑定到obj对象身上(不希望obj对象身上有函数)
    // 1.bind函数的基本使用
    // var bar = foo.bind(obj)
    // bar() // this -> obj

    // 2.bind函数的其他参数(了解)
    var bar = foo.bind(obj, "kobe", 18, 1.88)
    bar("james") //obj

 

内置函数 的 this : 

<body>
  
  <button>按钮</button>

  <script>
    // 内置函数(第三方库): 根据一些经验
    // 1.定时器  - window
    setTimeout(function() {
      console.log("定时器函数:", this)
    }, 1000)

    // 2.按钮的点击监听
    var btnEl = document.querySelector("button")
    btnEl.onclick = function() {
      console.log("btn的点击:", this) //元素本身
    }

    btnEl.addEventListener("click", function() {
      console.log("btn的点击:", this) //元素本身
    })

    // // 3.forEach
    var names = ["abc", "cba", "nba"]
    names.forEach(function(item) {
      console.log("forEach:", this) //window
    }, "aaaa")  //第三个参数就是改变this 的

  </script>

</body>

 

优先级 :  - 代码

  <script>

    function foo() {
      console.log("foo:", this)
    }

    // 比较优先级:

    // 1.显式绑定绑定的优先级高于隐式绑定
    // 1.1.测试一:apply高于默认绑定
    var obj = { foo: foo }
    obj.foo.apply("abc")
    obj.foo.call("abc")

    // 1.2.测试二:bind高于默认绑定
    var bar = foo.bind("aaa")
    var obj = {
      name: "why",
      baz: bar
    }
    obj.baz()


    // 2.new绑定优先级高于隐式绑定
    var obj = {
      name: "why",
      foo: function() {
        console.log("foo:", this)
        console.log("foo:", this === obj)
      }
    }
    new obj.foo()


    // 3.new/显式
    // 3.1. new不可以和apply/call一起使用

    // 3.2. new优先级高于bind
    function foo() {
      console.log("foo:", this)
    }
    var bindFn = foo.bind("aaa")
    new bindFn()


    // 4.bind/apply优先级
    // bind优先级高于apply/call
    function foo() {
      console.log("foo:", this)
    }
    var bindFn = foo.bind("aaa")
    bindFn.call("bbb")

  </script>

 

 

箭头函数 

  1.箭头函数不会绑定this[写了this的话,会跟上层的this一致,因为他是在找变量this所以找到了上一层的this] , 没有arguments属性

  2.箭头函数不能作为构造函数来使用 ( 不能和new一起来使用 , 会抛出错误  [ 因为es6后不会使用new,用class来代替了 ]) 

  3.箭头函数的简写

    箭头函数只有一个参数,那么( ) 可以省略 

    箭头函数的函数体只有一行代码,那么 { } 可以省略 , 并且 这行代码 的结果 会作为这个函数的返回值 默认返回

    默认返回值是一个对象,那么这个对象必须加( )  [ 这个在react中会经常使用 redux ]

    

 

posted @ 2022-07-18 15:32  杨建鑫  阅读(701)  评论(0编辑  收藏  举报