zoukankan      html  css  js  c++  java
  • javascript的this

    前言


    javascript 的 this 指向主要是依赖上下文对象决定,箭头函数例外。

    默认绑定


    在全局作用域下调用函数,函数的this默认指向window

    注意1:严格模式下,默认指向undefined

    function test() {
      console.log(this.a);
    }
    
    var a = 1;
    test(); // 1
    
    // 严格模式
    function test() {
      'use strict';
      console.log(this.a);
    }
    
    var a = 1;
    test(); // TypeEror 报错
    

    注意2:全局作用域下 var声明的变量会默认绑定到window,而letconst声明的变量不会

    let a = 1;
    var b = 1;
    
    window.a // undefined
    window.b // 1
    

    隐式绑定


    当函数引用有上下文对象时,this隐式绑定到这个上下文对象中。

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 1,
      test: test
    }
    
    var a = 2;
    
    obj.test(); // 1
    

    隐式丢失

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 1,
      test: test
    }
    
    var a = 2;
    
    // 隐式丢失,this 应用默认绑定规则
    var bar = obj.test; 
    bar() // 2
    

    显式绑定

    callapplybind等显式改变this指向。

    注意:非严格模式下,callapplybind等传入nullundefined会默认转为window

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 1
    }
    
    var a = 2;
    
    test(); // 2
    test.call(obj); // 1
    test.apply(obj); // 1
    
    var bTest = test.bind(obj);
    bTest(); // 1
    

    注意2:多次使用bindthis只会指向第一次bindthis

    function test() {
      console.log(this.a);
    }
    
    var obj1 = { a: 1 }
    var obj2 = { a: 2 }
    var obj3 = { a: 3 }
    
    var bind1 = test.bind(obj1);
    bind1(); // 1
    
    var bind2 = bind1.bind(obj2);
    bind2(); // 1
    
    var bind3 = bind2.bind(obj3);
    bind3(); // 1
    

    内置函数改变this指向

    function test() {
      console.log(this.a);
    }
    
    var obj = {
      a: 1
    }
    
    var arr = [1, 2, 3];
    arr.forEach(test, obj); // 打印 3 个 1
    

    new 绑定

    使用new操作符会产生如下步骤:

    1. 创建一个新的空对象。
    2. 将新对象与构造函数的prototype相连。
    3. 新对象绑定带构造函数的this
    4. 如果构造函数有返回值,且返回值是对象,则返回构造函数的返回值,否则返回新建的对象。
    function create() {
      let obj = new Object();
      
      let constructor = [].shift.call(arguments);
      
      // obj.__proto__ = constructor.prototype;
      Object.setPrototypeOf(obj, constructor.prototype);
      
      // 改变 this
      let res = constructor.apply(obj, arguments);
      
      const isObj = Object.prototype.toString.call(res) === '[object Object]';
      return isObj ? result : obj;
    }
    

    箭头函数


    箭头函数比较特殊,它有以下几个特点:

    1. 没有自身的this,在定义时默认绑定父级作用域的this,即采用词法作用域绑定this.

    2. 没有原型 prototype,无法使用 new 操作符,即不能作为构造函数.

    3. 无法使用callapplybind等显式改变其this.

      const test = () => console.log(this);
      let obj = {};
      
      test(); // window
      test.call(obj); // window
      
      const foo = test.bind(obj);
      foo(); // window
      
  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/guolao/p/12214804.html
Copyright © 2011-2022 走看看