箭头函数中的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();
原文地址:https://www.cnblogs.com/zppsakura/p/12755493.html