网站首页 > 技术文章 正文
apply 和 call 的区别
apply 和 call 都能改变函数的 this 指向,区别在于参数的不同,具体用法如下:
var fn = function (args) {
// do something
};
fn.call(this, arg1, arg2, ...); // call 的第二个参数是一个个的散列参数
fn.apply(this, [arg1, arg2, ...]) // apply 的第二个参数是一个数组
使用场景
比如取数组中的最大值:
var arr = [1, 4, 2, 5, 2, 6];
// 取最大
var max1 = Math.max.call(null, ...arr);
var max2 = Math.max.apply(null, arr);
再比如处理类数组,如 arguments:
var fn = function () {
var arr = Array.prototype.slice.call(arguments);
console.log(arr); //[1, 2, 3]
};
fn(1, 2, 3);
apply 和 call 的手写实现
对于apply,实现如下:
// es6 实现方式
Function.prototype.apply = Function.prototype.apply || function(ctx, arr) {
var context = Object(ctx) || window;
var fn = Symbol();
var result;
context[fn] = this;
if (!arr) {
result = context[fn]();
}
else {
result = context[fn](...arr);
}
delete context[fn];
return result;
}
// 利用 eval 实现方式
Function.prototype.apply = Function.prototype.apply || function(ctx, arr) {
var context = Object(ctx) || window;
var fn = Symbol();
var result;
context[fn] = this;
if (!arr) {
result = context[fn]();
}
else {
var args = [];
// 转成字符串
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
// 利用 eval 执行fn
result = eval('context[fn]('+ args +')');
}
delete context[fn];
return result;
}
对于call,实现如下:
// es6 实现
Function.prototype.call = Function.prototype.call || function(ctx, ...args) {
var context = Object(ctx) || window;
var fn = Symbol();
context[fn] = this; // this 就是要执行的函数
var result;
result = context[fn](...args);
delete context[fn];
return result;
}
// eval 实现
Function.prototype.call = Function.prototype.call || function(ctx) {
var context = Object(ctx) || window;
context.fn = this; // this 就是要执行的函数
var result;
var agrs = [];
for (var i = 1,len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
result = eval('context.fn(' + args + ')');
delete context.fn;
return result;
}
猜你喜欢
- 2024-11-16 3.1 Python高级编程-函数式编程工具
- 2024-11-16 面向对象编程的一些思考(面向对象编程的理解)
- 2024-11-16 知识总结-Java8 Stream函数式编程
- 2024-11-16 bind、call、apply 区别?如何实现一个bind?
- 2024-11-16 java 8新特性 常用内置函数式接口
- 2024-11-16 7、JavaScript 内置的常用对象有哪些?该对象常用的方法(必会)
- 2024-11-16 Java中“::”是什么含义(java中+是什么)
- 2024-11-16 Java 8 中的 Function:让代码从繁琐到简洁的魔法工具
- 2024-11-16 13万字详细分析JDK中Stream的实现原理(中)
- 2024-11-16 面试官问到.call()和.apply()怎么办?JavaScript高级技巧揭秘
- 标签列表
-
- 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)
- 最新留言
-