JS学习笔记(十二)
本系列更多文章,可以查看专栏 JS学习笔记
一、this对象
ES5中,函数内部存在两个特殊对象 arguments
、this
。(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方法
可以通过 call
和 apply
方法,来修改 this
的值。
1. 相同点
在调用函数且不需要传递参数时,call
和 apply
方法是相同的。
call
和apply
方法的第一个参数,用于指定this
指向的对象
- 非严格模式下
- 若
call
和apply
不传递任何实参,this
指向window
对象- 若
call
和apply
第一个参数为null
或undefined
,this
指向window
对象- 严格模式下
- 若
call
和apply
不传递任何实参,this
指向 空对象- 若
call
和apply
第一个参数为null
或undefined
,this
指向 空对象
// "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. 若取消第一行的注释,会转换为严格模式,因此在不传入任何值或第一个参数传入 null
或 undefined
时会报错。
严格模式下,代码运行情况如下图所示:
2. 不同点
在调用函数且需要传递参数时,call
和 apply
方法在使用上产生不同。
- 使用
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
方法和 call
或 apply
方法的最大不同:本质是创建新函数,不会直接调用新函数!!!
结尾
部分内容参考《ECMAScript 6 入门》《JavaScript权威指南》《JavaScript高级程序设计》,如有错误,欢迎评论区指正。