最开始还想把这个笔记名字改成 bind apply call 之前的区别,但是,想了想记录笔记还是要从原因开始,再到为什么再到怎么做。所以,还是改成 执行函数中改变 this 的指向以及方法。
bind,apply,call 都是执行函数时,用来改变 this 的指向。另外,apply、call 是立即执行,而 bind 是调用的时候才执行。
需要改变这个 this 的指向,是因为原来的 this 被污染了,需要重新再进行 this 指向,因为,this 指向的是被调用的父级作用域,而如果函数在另一个函数里面执行的时候,那么,这个 this 的指向的就是这个函数,而不是那个被执行函数原来的那个作用域。
举例:
const fighter = {
model: '700',
fire: function (res) {
console.log(this.model);
console.log(res);
},
};
setTimeout(function () {
fighter.fire();
}, 1000);
// underined
此时,setTimeout() 里面的函数 this 的指向是指向了 window,而 fighter.fire() 这个函数的执行 this是需要指向这个 fighter 的。所以,执行的时候就会 输出 undefined 。因为,在 setTimeout 这个域下找不到这个 model 的参数。这个就需要把 这个 this 的指向改成指向 fighter 这个对象。以下是改变 this 指向的方法。
call的第一个参数是 this 的指向,后面是一个传入参数的列表。
const fighter = {
model: '700',
fire: function (args1, args2) {
console.log(this.model);
console.log(args1);
console.log(args2);
},
};
setTimeout(function () {
fighter.fire.call(fighter, 'fire', '700');
}, 1000);
// 700
// fire
// 700
第一个参数是改变 this 的指向, 第二个以后的参数是分别进行传参。
使用 apply 改变 this 指向和 call 改变指向大致上方法是一样的,唯一有不同的就是传参是以单个参数(数组)进行传递,如下图:
const fighter = {
model: '700',
fire: function (args1) {
console.log(this.model);
console.log(args1);
},
};
let plane = fighter.fire;
setTimeout(function () {
plane.apply(fighter, ['1']);
}, 1000);
// 700
// 1
上面已经提到过,bind 的执行和前面的 call 和 apply 的执行是不一样的,call 和 apply 是立即执行一次。而 bind 是手动执行同时 bind 是永久改变 this 的指向。
const fighter = {
model: '700',
fire: function (args1 = 'none') {
console.log(this.model);
console.log(args1);
},
};
let plane = fighter.fire;
setTimeout(function () {
plane.bind(fighter, ['fire'])();
fighter.fire('fire-2');
}, 1000);
// output
// 700
// ['fire']
// 700
// fire-2
像这个例子,plane.bind(fighter, 'fire') 是需要手动执行才会触发,这是第一点。另一点是下面再次执行 fighter.fire('fire-2') 的时候,由于,前面已经使用过 bind 改变了 this 的指向。这个时候再次调用 fire 这个函数,就不需要再改变 this 的指向了,直接执行就可以。
判断一个数组的最大最小值,最简单的方法就是
const num = [1, 2, 6, 4, 8, 3, 78, 10];
console.log(Math.max(1, 2, 6, 4, 8, 3, 78, 10));
但是,Math.max 是不支持接受一个数组参数的,那么就需要利用 apply 的一个特性,就是将数组参数依次传递的特性,再执行。
const num = [1, 2, 6, 4, 8, 3, 78, 10];
console.log(Math.max.apply(null, num));
console.log(Math.min.apply(null, num));
第一个参数传递 null ,因为没有需要用到这个 this ,所以, 只要这个利用这个函数执行就可以。
可以理解为 最终的执行是相当于
Math.max(1, 2, 6, 4, 8, 3, 78, 10);
Math.min(1, 2, 6, 4, 8, 3, 78, 10);
function Plane(num) {
this.engine = num;
this.land = function () {
console.log(this.engine);
}
};
function Fighter(num) {
Plane.call(this, num);
};
const plane_1 = new Fighter('666');
plane_1.land();
这里在 Fighter 中 执行 Plane 同时 将 Plane 的指向 ,指向 Fighter 。那么,Plane 的 this 就指向了 fighter ,更简单的理解就是,这个时候 Plane 的函数体放在了 Fighter 中,也就是继承。
const obj = { 0: '12', 1: '2', length: 2 };
const array_1 = Array.prototype.slice.call(obj);
console.log(array_1);
const array_2 = [].slice.call(obj);
console.log(array_2);
下面这一段是 使用 一个 _that 保存了 this;
const obj = {
num: 123,
getNum: function () {
const _that = this;
setTimeout(function () {
console.log(_that.num);
}, 1000);
},
};
// output
// 123
等同于用 bind 改变 this 的指向的写法:
const obj_2 = {
num: 123,
getNum: function () {
setTimeout(function () {
console.log(this.num);
}.bind(this), 1000);
},
};
obj_2.getNum();
// output
// 123
以上是我对函数改变 this 指向方法的理解。
卧槽,今天的咖啡店来了一个漂亮的小姐姐,肤白貌美大长腿,emmmm思考一下怎么要微信好。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。