this与函数的四种调用模式
- 函数调用模式
- 方法调用模式
- 构造函数调用模式
- 上下文调用模式(借用方法模式)
函数调用模式
如果一个函数不是一个对象的属性时,就是被当做一个函数来进行调用的。此时this指向了window
function fn(){
console.log(this);// 指向window
}
fn();
方法调用模式
当一个函数被保存为对象的一个属性时,我们称之为一个方法。当一个方法被调用时,this被绑定到当前对象
const obj = {
sayHi:function(){
console.log(this);//在方法调用模式中,this指向调用当前方法的对象。
}
}
obj.sayHi();
构造函数调用模式
如果函数是通过new关键字进行调用的,此时this被绑定到创建出来的新对象上。
function Person(){
console.log(this);
}
Person();//this指向什么? window
var p = new Person();//this指向什么? Person{}
方法借用模式
也叫上下文模式,分为 apply 与 call,bind
call
call方法可以调用一个函数,并且可以指定这个函数的this指向
const RichWumon = {
name: "土豪",
say: function () {
console.log(this.name);
}
}
const obj = {
name: "屌丝"
}
RichWumon.say(); // 土豪
RichWumon.say.call(obj); // 屌丝
call将伪数组转成数组
伪数组不能使用数组的api,如果需要用数组api给伪数组添加元素,则需要使用call()方法
添加单个元素
let arr = {
0: 1,
1: 10,
2: 200,
length: 3
}
// 第一个参数是this,后面的是参数列表
;[].push.call(arr, 300)
console.log(arr) //{0: 1, 1: 10, 2: 200, 3: 300, length: 4}
添加一个数组
let arr = {
0: 1,
1: 10,
2: 200,
length: 3
}
// 第一个参数是this,后面的是参数列表
let data = [50, 60, 70, 80, 90]
;[].push.call(arr, ...data)
console.log(arr)
// arr:{0: 1, 1: 10, 2: 200, 3: 50, 4: 60, 5: 70, 6: 80, 7: 90, length: 8}
apply
apply()方法接受的是一个包含多个参数的数组
let arr = {
0: 1,
1: 10,
2: 200,
length: 3
}
// 如果有参数,参数需要定义为数组或伪数组
;[].push.apply(arr, [50, 60, 70, 80, 90])
console.log(arr)
bind方法
**bind()**方法创建一个新的函数, 可以绑定新的函数的this指向
var name = '张三'
function Fn() {
this.age = 1
console.log(this.name + this.age)
}
Fn() // 张三 1
// 返回值:新的函数
// 参数:新函数的this指向,当绑定了新函数的this指向后,无论使用何种调用模式,this都不会改变。
let obj = {
name: '小强'
}
// bind:返回一个新的函数,且函数中的this为你所传入的参数
const newFn = Fn.bind(obj)
newFn()