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
      
  • 相关阅读:
    SQL Server存储过程
    数据访问模式:数据并发控制(Data Concurrency Control)
    C#设计模式系列:观察者模式(Observer)
    awk内置字符串函数 awk 格式化输出
    使用MegaCli和Smartctl获取普通磁盘
    Shell之date用法
    linux 系统下查看raid信息,以及磁盘信息
    linux下proc里关于磁盘性能的参数
    hdparm测试硬盘性能
    查看现有运行的linux服务器有多少内存条
  • 原文地址:https://www.cnblogs.com/guolao/p/12214804.html
Copyright © 2011-2022 走看看