JS学习笔记(十二)call、apply、bind方法对this对象有什么影响?

JS学习笔记(十二)

本系列更多文章,可以查看专栏 JS学习笔记



一、this对象

ES5中,函数内部存在两个特殊对象 argumentsthis。(ES6中新增了new.target)

1. 标准函数中

在标准函数中,this引用的是把函数当成方法的调用上下文对象

  • 1. 在全局上下文中调用函数时this 指向 window对象
  • 2. 若通过xx.函数名()方式时this 指向 xx对象

注:以上特点,不考虑任何会修改 this 指向的方法

window.name = "Bill";
function sayHello() {
	console.log("this值为" + this.name);
}
// 在全局上下文调用函数
sayHello(); // this值为Bill
const obj = {
	name: "Jack"
};
// 为普通对象添加sayHello
obj.sayHello = sayHello;
// 使用普通对象调用方法
obj.sayHello(); // this值为Jack

2. 箭头函数中

在箭头函数中,this引用的是定义箭头函数的上下文

window.name = "Bill";
const obj = {
	name: "Jack"
};
// 箭头函数定义的位置
let sayHello = () => {
	console.log("this值为" + this.name);
};
// 在全局上下文调用函数
sayHello(); // this值为Bill
// 全局定义的sayHello和对象内部的sayHello是同一个函数【函数名是保存指针的变量】
obj.sayHello = sayHello;
// 使用普通对象调用方法
obj.sayHello(); // this值为Bill

事件回调定时回调中调用函数时,常使用箭头函数来确保 this 指向当前函数


二、call和apply方法

可以通过 callapply 方法,来修改 this 的值。

1. 相同点

在调用函数且不需要传递参数时callapply 方法是相同的。

  • callapply 方法的第一个参数,用于指定 this 指向的对象
    • 非严格模式下
      • callapply 不传递任何实参, this 指向window对象
      • callapply 第一个参数为 nullundefinedthis 指向window对象
    • 严格模式下
      • callapply 不传递任何实参, this 指向 空对象
      • callapply 第一个参数为 nullundefinedthis 指向 空对象
// "use strict";
window.color = "red";
const obj1 = {
	color: "yellow",
	sayColor() {
		console.log(this.color);
	}
};
let obj2 = {
	color: "blue"
};
obj1.sayColor(); // yellow;
obj1.sayColor.call(obj2); // blue;
obj1.sayColor.call(); // red
obj1.sayColor.apply(obj2); // blue;
obj1.sayColor.apply(); // red

1. 以上代码第一行被注释时,为非严格模式下,此时不传入任何值时,会将 this 值指定为 window 对象
2. 若取消第一行的注释,会转换为严格模式,因此在不传入任何值第一个参数传入 nullundefined 时会报错

严格模式下,代码运行情况如下图所示:

在这里插入图片描述

2. 不同点

在调用函数且需要传递参数时callapply 方法在使用上产生不同。

  • 使用call 方法时,接受函数参数
    • call 方法的第 2 个-第 n+1 个参数,作为实际调用的函数的第 1 个-第 n 个参数
    • xx.函数名.call(this指定值,函数参数1,...,函数参数n)
  • 使用apply 方法时,接受函数参数
    • apply 方法的第 2个参数,接收一个数组,数组中的第 1 个-第 n 个值,作为实际调用的函数的第 1 个-第 n 个参数
    • xx.函数名.apply(this指定值,[函数参数1,...,函数参数n])
const o1 = {
	k: 2,
	sum(a, b) {
		// 求和后 乘 放大系数k
		return (a + b) * this.k;
	}
};
const o2 = {
	k: 5
};
// 为 o2创建一个新函数
o2.sum = o1.sum.bind(o2);
let result1 = o2.sum(5, 10);
console.log(result1); // 75
// 创建一个新函数,并接受参数
let result2 = o1.sum.bind(o2, 5, 10)();
console.log(result2); // 75

三、bind方法

在指定 this 值后,会创建一个新函数,不会立即执行

  • 使用方法,类似于 call 方法,但不会立即执行新函数
    • bind 方法的第 1 个参数,指定 this 的值
    • bind 方法的第 2 个-第 n+1 个参数,作为函数的第 1 个-第 n 个参数
  • 常见用法
    • 添加新函数:xx1.函数名 = xx2.函数名.bind(this指定值); xx1.函数名(函数参数1,...,函数参数n);
    • 立即执行新函数:xx.函数名.bind(this指定值,函数参数1,...,函数参数n)()
const o1 = {
	k: 2,
	sum(a, b) {
		// 求和后 乘 放大系数k
		return (a + b) * this.k;
	}
};
const o2 = {
	k: 5
};
// 为 o2创建一个新函数
o2.sum = o1.sum.bind(o2);
let result1 = o2.sum(5, 10);
console.log(result1); // 75
// 创建一个新函数,并接受参数
let result2 = o1.sum.bind(o2, 5, 10)();
console.log(result2); // 75

bind 方法和 callapply 方法的最大不同:本质是创建新函数,不会直接调用新函数!!!


结尾

部分内容参考《ECMAScript 6 入门》《JavaScript权威指南》《JavaScript高级程序设计》,如有错误,欢迎评论区指正。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想要大口炫榴莲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值