1. 对this对象的理解:this 是执行上下文中的一个属性,它指向最后一次调用这个方法的对象。
* 任何函数本质上都是通过某个对象来调用的,如果没有直接指定就是window
* 所有函数内部都有一个变量this
* 它的值是调用函数的当前对象
2. 不同情况下this的值
* test(): window
* p.test(): p
* new test(): 新创建的对象
* p.call(obj): obj
function Person(color) {
console.log(this)
this.color = color;
this.getColor = function () {
console.log(this)
return this.color;
};
this.setColor = function (color) {
console.log(this)
this.color = color;
};
}
Person("red"); //this是谁? window
var test = p.setColor;
test(); //this是谁? window
function fun1() {
function fun2() {
console.log(this);
}
fun2(); //this是谁? window
}
fun1();
var p = new Person("yello"); //this是谁? p
p.getColor(); //this是谁? p
var obj = {};
p.setColor.call(obj, "black"); //this是谁? obj
3. 什么时候需要改变this的值
举个栗子:
当函数没有指定对象去调用的时候,则默认window调(this 指向window), 为了使this指向特定对象可通过bind修改this指向
const module = {
x: 42,
getX: function () {
return this.x;
},
};
console.log(module.getX());
// Expected output: 42
const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined
const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42
4. 如何改变this的值
- 使用ES6箭头函数(this 始终指向函数声明时所在作用域下的this值)
var a = 1;
var obj = {
a: 2
};
function fun () {
var a = 3;
let f = () => console.log(this.a);
f();
};
fun();//1
fun.call(obj);//2
// fun直接调用,fun的上下文中的this值为window,注意,这个地方有点绕。fun的上下文就是此箭头函数所在的上下文,因此此时f的this为fun的this也就是window。
//fun.call(obj)再次调用的时候,新的上下文创建,fun此时的this为obj,也就是箭头函数的this值。
- 在函数内部暂存 _this=this
- JavaScript 提供了call、apply、bind这三个方法来切换this的指向
5. call、apply、bind方法对this的影响?
这三个方法都可以显示的指定调用函数的 this 指向:
- call 方法接收的参数,第一个是 this 绑定的对象;后面的参数(数量不固定)则是函数调用时所需的参数, 每个参数被依次传入函数。
let obj = {
x: 0,
name: 'obj1'
}
function fn1(x, y) {
console.log(this)
console.log(x + y)
}
fn1.call(null, 1, 2) //this指向window 3
fn1.call(obj, 1, 2) //this指向obj 3
- apply 方法接收两个参数:一个是 this 绑定的对象,一个是参数数组。
let obj = {
x: 0,
name: 'obj1'
}
function fn2(arr) {
console.log(this)
console.log(arr)
}
fn2([1, 2, 7]) // this指向window [1, 2, 7]
fn2.apply(obj, [1, 2, 7]) //this指向obj 1
- bind 方法通过传入一个对象,返回一个 this 绑定了传入对象的新函数。我们必须要手动去调用该新函数才会执行。
let obj = {
x: 1,
name: 'obj1'
}
let ob = {
y: 4,
name: 'obj1'
}
function fn3(o, z) {
console.log(this)
return (this.x + o.y + z)
}
fn3.bind(obj, ob) // 不执行 无输出
fn3.bind(obj, ob)() // 执行 this指向obj
var m = fn3.bind(obj, ob);
console.log(m(3)); //this指向obj 8 (柯里化)
apply,call,bind三者的区别
- 三者都可以改变函数的this对象指向。
- 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
- 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
- bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行 。