zoukankan      html  css  js  c++  java
  • 箭头函数中的this

    普通函数中的this

    1、this总是代表他的直接调用者(js的this是执行上下文),例如obj.func,那么func中的this就是obj,this的指向在函数创建的时候决定不了,调用的时候才能决定。它遵循谁调用就指向谁

    var o = {
        a:10,
        b:{
            a:12,
            fn:function(){
                console.log(this.a); 
            }
        }
    }
    o.b.fn();
    

    2、在默认情况下(非严格模式下,未使用‘use strict’),没找到直接调用者,则this指的是window(约定俗成)

    function a(){
        var name = "javascript";
        console.log(this.name); 
        console.log(this); 
    }
    a();
    

    3、在严格模式下,没有直接调用者的函数中的this是undefind

    "use strict"
    function a(){
        var name = "javascript";
        console.log(this); 
    }
    a();
    

    4、使用call,apply,bind(ES5新增)绑定的,this指的是绑定的对象

    var name = 'sally';
     
    function sayName(){
        return this.name;
    }
    function sayName2(){
        return this.name
    }
     
    var o = {
        'name':'John',
        sayName:sayName,
        sayName2:sayName2.bind(window)
    };
    console.log(o.sayName());
    console.log(o.sayName2());
    

    在使用 this 时,为了避坑,你要谨记以下三点:

    • 当函数作为对象的方法调用时,函数中的 this 就是该对象;
    • 当函数被正常调用时,在严格模式下,this 值是 undefined,非严格模式下 this 指向的是全局对象 window;
    • 嵌套函数中的 this 不会继承外层函数的 this 值。

    箭头函数中的this

    箭头函数有两大要点:
    1、箭头函数中,call 和 apply 会忽略掉 this 参数。
    这其实是“表象”,实际上是因为箭头函数的 this 是指向父级的 this,因为箭头函数自身没有 this,所以无法修改自身的 this,从而言之 “忽略”。

    var a = {say: function() {
    	var fn = (() => {
    		console.log(this)
    	}).bind(window)
    	fn()
    }}
    a.say()
    

    2、箭头函数的 this ,永远是跟随父级的 this 的。
    箭头函数的 this 是从当前箭头函数逐级向上查找 this,如果找到了,则作为自己的 this 指向,如果没有则继续向上查找。而父级的 this 是可变的,所以箭头函数的 this 也可跟随父级而改变。

    var flag = "996";
    function person(fg) {
      let o = new Object();
      o.flag = fg;
      o.getVal = () => {
        console.log(this);
      };
      return o;
    }
    let pp = new person("251");
    pp.getVal();
    
    var x = 11;
    var obj = {
      x: 22,
      methods: {
        x: 33,
        // say: function() {
        //     console.log(this.x)
        // },
        say2: () => {
          console.log(this.x);
        },
      },
    };
    obj.methods.say2();
    

    由于箭头函数绑定了词法作用域,它返回上一级函数调用的this绑定。因此,想修改箭头函数“本身”的 this 是做不到的,但是可以采用变更父级的 this 来达到变更子箭头函数的 this。比如:通过使用bind改变父级inner函数的this,来达到改变子箭头函数getval的this指向。
    箭头函数不使用 this 的四种标准规则,而是根据外层(函数或者全局)作用域来决 定 this

    function outer() {
      var inner = function () {
        var obj = {};
        obj.getVal = () => {
         console.log('====================================');
         console.log(this);
         console.log('====================================');
        };
        return obj;
      };
      return inner;
    }
    outer().bind(outer)().getVal();
    

    箭头函数注意点:

    1、typeof 运算符和普通的function一样

    var func = (a) => a;
    console.log(typeof func);
    

    2、instanceof也返回true,表明也是Function的实例

    var func = (a) => a;
    console.log(func instanceof Function);
    

    3、this固定,不再善变

    function father() {
      this.data = [1, 2, 3, 4];
      let o = new Object();
      o.a = 1;
      o.getVal = () => {
        console.log(this.data);
      };
      return o;
    }
    var ff = new father();
    ff.getVal();
    
    function father() {
      this.data = [1, 2, 3, 4];
      let o = new Object();
      o.a = 1;
      o.getVal = function () {
        console.log(this.data);
      };
      return o;
    }
    var ff = new father();
    ff.getVal();
    

    4、箭头函数不能用new

    var Person = (name, age) => {
      this.name = name;
      this.age = age;
    };
    var p = new Person("John", 33);
    

    5、不能使用argument, 可用...rest代替,因为在箭头函数中arguments指向的对象并不是当前函数所属的arguments,而是上级函数的arguments,所以需要将箭头函数转为function

    var func = () => {
      console.log(arguments);
    };
    func(123, 4);
    
    var func = (...value) => {
      console.log(value);
    };
    func(55, 6, 7);
    

    思考:

    var flag = "996";
    function person(fg) {
      let o = new Object();
      o.flag = fg;
      o.getVal = () => {
        console.log(this);
      };
      this.a = 1;
      console.log("======aaaaa==============================");
      console.log(this);
      console.log("====================================");
      return o;
    }
    let pp = new person("251");
    pp.getVal();
    console.log("====ppppp================================");
    console.log(pp);
    console.log("====================================");
    
    var flag = 996;
    function person(fg) {
      let o = new Object();
      o.flag = fg;
      o.getval = () => {
        console.log(this);
      };
      this.a = 1;
      return true;
    }
    var p2 = new person("251"); 
    console.log(p2.a);
    

    关于new操作符:
    1、由于person函数返回的是一个对象(null除外),所以在new的时候返回的是 person函数返回的o对象,并没有返回person函数的this给实例对象。
    2、如果person函数返回的是一个【数字、字符串、布尔等】,那么new的时候回忽略返回值,而是仍然会返回person的this给实例对象。

    x = 11;
    var obj = function () {
      x = 22;
      var methods = function () {
        x = 33;
        var say = () => {
          console.log(this);
        };
        return say;
      };
      return methods;
    };
    
    obj()()();
    
    var x = 11;
    var obj = function () {
      var x = 22;
      var methods = function () {
        var x = 33;
        var say = function () {
          var x = 44;
          console.log(this.x);
        };
        return say();
      };
      return methods();
    };
    
    obj();
    
  • 相关阅读:
    验证身份证
    base64.js
    mysql常用操作
    drop、truncate和delete的区别
    安装mysql
    一些常用计算
    nuxt+vant+rem项目构建
    vue2安装sass 预编译
    vant ui rem配置流程
    关于vue项目和内嵌iframe页面之间的通信问题
  • 原文地址:https://www.cnblogs.com/zpsakura/p/12755493.html
Copyright © 2011-2022 走看看