zoukankan      html  css  js  c++  java
  • JavaScript中的this

    引子

    本文是看完《你不知道的js》这本书中关于this的介绍后写的,相当于是读书笔记,把书中的重点总结了出来。如果你看完本文还有什么不懂的话,可以直接看《你不知道的js》这本书,写的灰常好。

    概要

    • 函数被new调用,this是新构建的对象;
    • 函数被硬绑定(call、apply、bind)后调用,this是指定绑定的对象;
    • 函数被持有自己的环境对象调用,this是该环境对象;
    • 函数直接被调用,this是全局对象windowstrict mode下是undefined

    如果上面说的四种情况你都懂的话,本文就不太适合你了;

    this是什么

    this是函数执行时建立的一个绑定,指向什么是由函数执行时确定的;
    所以判断this指向什么,要先看函数在哪执行,然后再判断this的指向。

    判断this指向的四种规则

    • 默认绑定

    函数被直接执行,this默认绑定的是window对象,严格模式下是undefined。例如:

    function foo() {
      console.log(this) // window
    }
    foo() // 函数在直接执行,this 指向 window
    
    • 隐式绑定

    隐式绑定需要考虑函数执行时是否有拥有者对象,this一般指向该对象。例如:

    let obj = {
      foo: function () {
        console.log(this) // obj
      }
    }
    obj.foo() // 函数执行时有个拥有者对象 obj,所以 this 指向 obj
    

    需要注意的是,隐式绑定会丢失它的绑定。一般会退回到默认绑定。例如:

    let obj = {
      foo: function () {
        console.log(this)
      }
    };
    let baz = obj.foo
    baz() // window,函数执行时才绑定 this,相当于直接执行,this 绑定到 window 上
    obj.foo() // obj,隐式绑定,this 指向 obj
    

    当我们传递回调函数时,隐式绑定也会丢失它的绑定。比如:

    let obj = {
      foo: function () {
        console.log(this)
      }
    };
    function doFoo(fn) {
      fn()
    }
    doFoo(obj.foo) // window
    // 参数传递相当于一种赋值,
    // 这里是 obj.foo 赋值给 fn,fn 函数执行时,this 绑定到 window
    obj.foo() // obj , 隐式绑定,this 指向 obj
    
    • 明确绑定

    有隐式绑定就有明确绑定,它是使用call、apply、bind这些方法强行改变this的指向。比如:

    function foo() {
        console.log( this.a )
    }
    
    let obj = {
        a: 2
    };
    
    foo.call( obj ); // 2, 通过 call 方法强行让 this 指向 obj
    
    • new 绑定

    通过new生成的对象,this指向的是新生成的对象。例如:

    function foo(a) {
        this.a = a
    }
    let bar = new foo( 2 )
    console.log( bar.a ) // 2, 
    // new 构建的对象,this 指向新构建出来的对象,
    // 至于为什么会这样,跟 new 干了啥有关;
    

    一些特例

    • 间接引用

    看个栗子:

    function foo() {
      console.log( this )
    }
    let o = { foo: foo }
    let p = { }
    
    o.foo() // o
    (p.foo = o.foo)() // window
    

    赋值表达式p.foo = o.foo的结果是指向函数的引用,在执行时相当于foo()this指向window

    • 箭头函数

    从上面我们可以看出,this是函数执行时,才绑定的。但是箭头函数不同,箭头函数的this是编写时,被绑定到调用者的外层;比如:

    function foo() {
      let fn = () => {
        console.log( this )
      }
      return fn()
    }
    foo() // window
    
  • 相关阅读:
    用react重构个人网站 3-23
    用react重构个人网站 3-22
    React官方文档笔记之快速入门
    .Net多线程编程—同步机制
    .Net多线程编程—Parallel LINQ、线程池
    .Net多线程编程—并发集合
    .Net多线程编程—任务Task
    【翻译】MongoDB指南/聚合——聚合管道
    【翻译】MongoDB指南/CRUD操作(四)
    【翻译】MongoDB指南/CRUD操作(三)
  • 原文地址:https://www.cnblogs.com/yangrenmu/p/10548040.html
Copyright © 2011-2022 走看看