前言
JavaScript
中共有五种调用模式,分别是:函数调用模式、方法调用模式、构造器调用模式、 apply/call
调用模式,本文就来探究一下这几种调用模式的区别及其上下文,也就是 this
指向问题。
函数调用模式
函数调用模式就是调用直接声明函数,其中的 this
在非严格模式下是 Window
对象,在严格模式下是 undefined
。
function a() {
console.log(this);
};
a();
var fnObj = {
name: 'objFunction',
outFn: function () {
console.log(this);
let innerFn = function() {
console.log(this);
}
innerFn();
}
}
fnObj.outFn();
方法调用模式
方法模式就是以函数表达式的方式将函数赋值给一个对象的属性,然后通过对象来调用函数,此时 this
就是调用函数的对象。在这种模式下,只需要记住,是哪个对象调用的, this
就绑定哪个对象
var fnObj = {
name: 'objFunction',
outFn: function () {
console.log(this);
}
}
fnObj.outFn();
构造器调用模式
我们可以通过 new
关键字调用构造器函数,其中的 this
就会被绑定到新对象上
function CreateObj(name, age) {
this.name = name;
this.age = age;
this.showThis = function () {
console.log(this);
}
}
var obj = new CreateObj('knight', '24');
console.log(obj);
obj.showThis()
apply/call 调用模式
Apply/call
方法可以我们选择 this
的值,此时 this
就是我们调用 call
方法时的第一个参数,如果我们不指定则为 Window
对象。
apply
方法和 call
方法及 bind
方法的区别:
apply
传给要调用的方法的参数使用数组call
一个一个传bind
是返回绑定this
的对象,我们可以调用这个对象
var obj = {
name: 'knight',
age: 23,
};
function aaa(a, b) {
console.log(this);
console.log(`${a} : ${b}`);
};
aaa.call(obj, 1, 2);
aaa.apply(obj, [3, 4]);
aaa.bind(obj)(5, 6);
aaa.call();
备注
箭头函数没有上下文,即没有 this
,再箭头函数中使用 this
则是使用父作用域的上下文即 this
,若父作用域也没有上下文,就一直向上找
var obj = {
name: 'knight',
age: 23,
}
function fun() {
(() => {
console.log('箭头函数');
console.log(this);
})();
let a = function() {
console.log('普通函数');
console.log(this);
}();
}
fun.call(obj);