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 1097. Deduplication on a Linked List (链表)
    PAT 1096. Consecutive Factors
    PAT 1095. Cars on Campus
    PAT 1094. The Largest Generation (层级遍历)
    PAT 1093. Count PAT's
    PAT 1092. To Buy or Not to Buy
    PAT 1091. Acute Stroke (bfs)
    CSS:word-wrap/overflow/transition
    node-webkit中的requirejs报错问题:path must be a string error in Require.js
    script加载之defer和async
  • 原文地址:https://www.cnblogs.com/mtxcat/p/13488568.html
Copyright © 2011-2022 走看看