前言
最近在写 React 项目, 然后补习了下 es6 的 class 。发现 实例方法被赋值后 this 指向 undefined, 这里对 this 指向作一次总结。
一、通过 函数的 调用方式 来判断 this 指向
1. 函数名();
通过 函数名();
方式调用函数, 则该函数中的 this 指向 global/window
function fn() {
console.log(this);
}
fn(); // window
2. 对象.方法名();
通过 对象.方法名();
方式调用函数,则该函数中的 this 指向 当前的 对象
var obj = {
speak() {
console.log(this);
}
}
obj.speak(); // obj
3. 立即执行函数
立即执行函数
中的 this 指向 global/window
;(function() {
console.log(this); // window
})();
4. apply/call
通过 apply/call
方式调用函数, 则该函数中的 this 指向 与 apply/call
的第一个参数有关。
function fn() {
console.log(this);
}
var obj = {
name: 'obj'
}
fn.apply(obj); // obj
fn.call(obj); // obj
fn.call(); // window
fn.apply(null); // window
二、 3种其他情况
arrow ,bind ,call/apply 的权重
arrow > bind > call/apply
5. bind 函数
bind 创建一个新函数,并不会改变原函数
语法: fnNew = fn.bind(thisArg[, arg1[, arg2[, ...]]])
函数 fnNew 中的 this 始终指向 thisArg 对象,与函数调用方式无关
function fn () {
console.log(this);
}
var obj = {
name: 'obj'
};
var fnNew = fn.bind(obj);
fn(); // window
fn.call(null); // window
fnNew(); // obj
fnNew.call(null); // obj
6. arrow 函数
箭头函数 中的 this 指向 与 函数声明时候所处环境中 的 this 指向一致
var fn = () => {
console.log(this);
}
var obj = {
name: 'obj'
};
var fnNew = fn.bind(obj);
fn(); // window
fn.call(obj); // window
fnNew(); // window
7. class
当一个对象调用静态或原型方法时,如果该对象没有“this”值(或“this”作为布尔,字符串,数字,未定义或null) ,那么“this”值在被调用的函数内部将为 undefined
。不会发生自动包装。即使我们以非严格模式编写代码,它的行为也是一样的,因为所有的函数、方法、构造函数、getters或setters都在严格模式下执行。因此如果我们没有指定this的值,this值将为undefined。
class Animal {
static speak() {
console.log(this);
}
eat() {
console.log(this);
}
}
var animal = new Animal();
animal.eat(); // animal
// animal.speak(); // Uncaught TypeError: animal.speak is not a function
Animal.speak(); // Animal
let eat = animal.eat;
let speak = Animal.speak;
eat(); // undefined
speak(); // undefined