日期:2021年8月18日
作者:Commas
注释:如果您觉得有所帮助
,帮忙点个赞
,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^
(ง •_•)ง 积跬步以致千里,js的学习笔记
1.01365 = 37.7834;0.99365 = 0.0255
1.02365 = 1377.4083;0.98365 = 0.0006
文章目录
一、bind、call和apply比较
作用:
bind
、call
和apply
都是用于改变函数体内this
的指向,即它们都是为了改变某个函数运行时的上下文而存在的;
比较内容 | bind | call | apply |
---|---|---|---|
语法 | fn.bind(thisArg[, arg1[, arg2[, ...]]]) | fn.call(thisArg[, arg1[, arg2[, ...]]]) | fn.apply(thisArg, [argsArray]) |
第一个参数 | 函数上下文的对象thisArg | 函数上下文的对象thisArg | 函数上下文的对象thisArg |
剩下的参数 | 可选,一个参数列表,而不是单个数组 | 可选,一个参数列表,而不是单个数组 | 可选,函数参数所组成的数组(Array)或伪数组(E6支持,ArrayLike类数组,) |
执行情况 | 返回新函数—绑定函数 | 返回函数执行结果 | 返回函数执行结果 |
二、bind与call的比较
比较 | bind | call |
---|---|---|
语法 | fn.bind(thisArg[, arg1[, arg2[, ...]]]) | fn.call(thisArg[, arg1[, arg2[, ...]]]) |
相同点 | thisArg+参数列表(非数组) | thisArg+参数列表(非数组) |
不同点 | 返回新函数体(绑定函数) | 返回函数执行结果 |
(2-1)bind
语法:
fn.bind(thisArg[, arg1[, arg2[, ...]]])
bind
方法第一个参数作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组,并且返回一个新的函数(绑定函数);
一个参数:
let walk = function(){
return(`${this.name}:I can walk`);
};
//(1)dog
let dog = {name:"dog"};
let dogWalk = walk.bind(dog);
console.log(dogWalk);
//ƒ(){return(`${this.name}:I can walk`);}
console.log(dogWalk());
//控制台输出:dog:I can walk
//(2)cat
let cat = {name:"cat"};
let catWalk = walk.bind(cat);
console.log(catWalk);
//ƒ(){return(`${this.name}:I can walk`);}
console.log(catWalk());
//控制台输出:cat:I can walk
多个参数:
let add = function(x,y,z){
console.log(arguments);
return x+y+z;
};
//x,y,z三个参数,x的萝卜坑已经被bind中的10给占了
//剩余参数位置只有y,z
let sum = add.bind(null,10);
//(1)萝卜坑刚好填满;
console.log(sum(20,30));
//控制台输出:
//Arguments(3) [10, 20, 30, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
//(2)萝卜坑填满,多出的40只加入到arguments;
console.log(sum(20,30,40));
//控制台输出:
//Arguments(4) [10, 20, 30, 40, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
(2-2)call
语法:
fn.call(thisArg[, arg1[, arg2[, ...]]])
call
方法第一个参数作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组,并且返回函数的执行结果;- 另一个值得注意的是,后面参数个数要与原函数个数一致,所谓的萝卜坑要一致,不然会出问题的
一个参数:
let walk = function(){
return(`${this.name}:I can walk`);
};
//(1)dog
let dog = {name:"dog"};
let dogWalk = walk.call(dog);
console.log(dogWalk);
//控制台输出:dog:I can walk
//(2)cat
let cat = {name:"cat"};
let catWalk = walk.call(cat);
console.log(catWalk);
//控制台输出:cat:I can walk
多个参数:
let add = function(x,y,z){
console.log(arguments);
return x+y+z;
};
//(1)参数刚好
let sum1 = add.call(null,10,20,30);
console.log(sum1);
//控制台输出:
//Arguments(3) [10, 20, 30, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
//(2)多参数
let sum2 = add.call(null,10,20,30,40);
console.log(sum2);
//控制台输出:
//Arguments(4) [10, 20, 30, 40, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
//(3)少参数
let sum3 = add.call(null,10);
console.log(sum3);
//控制台输出:
//Arguments [10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//NaN
小结:当传递的参数较少的时候,
如果需要返回一个新函数,那么用bind
;
如果需要立即返回执行结果就,那么用call
;
三、call与apply的比较
比较 | call | apply |
---|---|---|
语法 | fn.call(thisArg[, arg1[, arg2[, ...]]]) | fn.apply(thisArg, [argsArray]) |
相同点 | 返回函数执行结果 | 返回函数执行结果 |
不同点 | thisArg+参数列表(非数组) | thisArg+数组(或类数组) |
(3-1)call
语法:
fn.call(thisArg[, arg1[, arg2[, ...]]])
- 描述与示例等详情,可见上述的 (2-2)call 小节,此处不再赘述;
(3-2)apply
语法:
fn.apply(thisArg, [argsArray])
apply
方法传入两个参数:一个也是作为函数上下文的对象,另外一个是作为函数参数所组成的数组(ES6也支持伪代码,又称类数组,ArrayLike),并且返回函数的执行结果;
一个参数:
//(1)dog
let dog = {name:"dog"};
let dogWalk = walk.apply(dog);
console.log(dogWalk);
//控制台输出:dog:I can walk
//(2)cat
let cat = {name:"cat"};
let catWalk = walk.apply(cat);
console.log(catWalk);
//控制台输出:cat:I can walk
多个参数:
let add = function(x,y,z){
console.log(arguments);
return x+y+z;
};
//(1)数组元素个数=原参数个数
let sum1 = add.apply(null,[10,20,30]);
console.log(sum1);
//控制台输出:
//Arguments(3) [10, 20, 30, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
//(2)数组元素个数>原参数个数
let sum2 = add.apply(null,[10,20,30,40]);
console.log(sum2);
//控制台输出:
//Arguments(4) [10, 20, 30, 40, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//60
//(3)数组元素个数<原参数个数
let sum3 = add.apply(null,[10]);
console.log(sum3);
//控制台输出:
//Arguments [10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
//NaN
小结:当需要立即返回函数执行结果的时候,
如果传递的参数少,那么用call
;
如果传递的参数多,或者已有对应的数组,那么用apply
;
四、解决低版本浏览器中未定义bind函数问题
if (!Function.prototype.bind) {
Function.prototype.bind = function () {
var self = this, // 保存原函数
context = [].shift.call(arguments), // 保存需要绑定的this上下文
args = [].slice.call(arguments); // 剩余的参数转为数组
// 返回一个新函数
return function () {
self.apply(context,
[].concat.call(args, [].slice.call(arguments))
);
};
};
};
参考文章:
1、《JavaScript 中 apply 、call 的详解》
2、《call、apply、bind三者的用法和区别》
3、《bind、call、apply的区别与实现原理》
4、《javascript中call()、apply()、bind()的用法终于理解》
版权声明:本文为博主原创文章,如需转载,请给出:
原文链接:https://blog.csdn.net/qq_35844043/article/details/119778163