网站首页 > 技术文章 正文
执行函数中改变 this 的指向以及方法
最开始还想把这个笔记名字改成 bind apply call 之前的区别,但是,想了想记录笔记还是要从原因开始,再到为什么再到怎么做。所以,还是改成 执行函数中改变 this 的指向以及方法。
改变 this 的指向的方法和执行
bind,apply,call 都是执行函数时,用来改变 this 的指向。另外,apply、call 是立即执行,而 bind 是调用的时候才执行。
为什么需要改变这个 this 的指向
需要改变这个 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 指向
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 指向
使用 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 改变 this 指向
上面已经提到过,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);
保存 this
下面这一段是 使用 一个 _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 指向方法的理解。
wocao,今天的咖啡店来了一个漂亮的小姐姐,肤白貌美大长腿,emmmm思考一下怎么要微信好。
- 上一篇: 你不一定了解的最新JS知识点
- 下一篇: js面试题整理(接上篇文章)
猜你喜欢
- 2024-11-21 浅析GIF 格式图片的存储与解析
- 2024-11-21 如何用2 KB代码实现3D赛车游戏?2kPlus Jam大赛了解一下
- 2024-11-21 快速了解ES6的代理与反射
- 2024-11-21 「实战」蘑菇街 PC 端首页,瀑布流布局的实现原理与细节技巧
- 2024-11-21 Knative 驾驭篇:带你 '纵横驰骋' Knative 自动扩缩容实现
- 2024-11-21 ECMAScript 6使用教程总结
- 2024-11-21 一道二进制子串算法,让面试官都解不出来?
- 2024-11-21 高级前端进阶,为什么要使用call、apply、bind?
- 2024-11-21 碎片时间学编程「202]:分组数组元素
- 2024-11-21 从入门到入土:Lambda完整学习指南,包教包会(上)
- 标签列表
-
- content-disposition (47)
- nth-child (56)
- math.pow (44)
- 原型和原型链 (63)
- canvas mdn (36)
- css @media (49)
- promise mdn (39)
- readasdataurl (52)
- if-modified-since (49)
- css ::after (50)
- border-image-slice (40)
- flex mdn (37)
- .join (41)
- function.apply (60)
- input type number (64)
- weakmap (62)
- js arguments (45)
- js delete方法 (61)
- blob type (44)
- math.max.apply (51)
- js (44)
- firefox 3 (47)
- cssbox-sizing (52)
- js删除 (49)
- js for continue (56)
- 最新留言
-