首页 > 试题广场 >

使用 apply 调用函数

[编程题]使用 apply 调用函数
  • 热度指数:52852 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
实现函数 callIt,调用之后满足如下条件
1、返回的结果为调用 fn 之后的结果
2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
示例1

输入

输出

function callIt(fn) {
    var argu = Array.prototype.slice.call(arguments);
    argu.shift();
    return fn.apply(this,argu);
}

发表于 2016-08-04 16:01:14 回复(0)
更多回答
推荐
因为arguments并非真正的数组,因此要获得callIt的第一个参数之后的所有参数,不能直接使用slice方法截取,需要先将arguments转换为真正的数组才行。有两种常见的方法,一是使用slice方法:var args = Array . prototype . slice . call ( arguments );二是循环遍历逐一填入新数组。在获得了args之后,就可以调用apply来执行传入的函数参数。
function callIt(fn) {
    //将arguments转化为数组后,截取第一个元素之后的所有元素
    var args = Array.prototype.slice.call(arguments,1);
    //调用fn
    var result = fn.apply(null,args);
    return result;
}


编辑于 2015-08-18 21:05:42 回复(23)
var callIt = (fn) => fn.apply(null, [].splice.call(arguments, 1));

发表于 2017-03-14 18:58:29 回复(0)
function callIt(fn) {
    var a = Array.prototype.slice.call(arguments)
    a.shift()
    var str = a.toString()
    return  eval('fn('+str+')')
}

发表于 2019-03-23 13:02:58 回复(2)
arguments并非真正的数组,因此要获得callIt的第一个参数之后的所有参数,不能直接使用slice方法截取,需要先将arguments转换为真正的数组。常见的方法是循环遍历逐一填入新数组。在获得了args之后,就可以调用apply来执行传入的函数参数。
function callIt(fn) {
    var arr = [];
    for(var i = 1;i<arguments.length;i++) {
        arr.push(arguments[i]);
    }
    return fn.apply(callIt,arr);
}


发表于 2022-03-27 21:46:07 回复(0)
function callIt(fn) {
    return fn(...[...arguments].slice(1))
}

发表于 2022-01-07 10:03:06 回复(0)
function callIt(fn) {
    return fn.apply(this, Array.prototype.slice.call(arguments, 1))
}

发表于 2021-09-08 23:03:55 回复(0)
// FED42使用apply调用函数

// 描述
// 实现函数 callIt,调用之后满足如下条件
// 1、返回的结果为调用 fn 之后的结果
// 2、fn 的调用参数为 callIt 的第一个参数之后的全部参数

// 示例1
// 输入:
// 无

// 输出:
// 无

function callIt(fn) {
    // 方法1 使用arguments,利用...拓展将其变为数组
    let args = [...arguments];
    return args[0].apply(this, args.slice(1));

    // // 另一种实现
    // let args = [...arguments];
    // let f = args[0];
    // args.shift();
    // return f.apply(this, args);

    // // 方法2 用Array.prototype.slice.call将参数arguments转为数组,并去掉第一个元素
    // let args = Array.prototype.slice.call(arguments, 1);
    // return fn.apply(null, args);

    // // 另一种实现,用空数组调用.slice.call方法
    // let args = [].slice.call(arguments, 1);
    // return fn.apply(null, args);
}


发表于 2021-08-10 19:09:51 回复(0)
function callIt(fn) {
    return fn.apply(this, [...arguments].slice(1))
}

发表于 2021-08-08 00:01:29 回复(0)
function callIt(fn, ...args) {
    return fn(...args);
}

发表于 2021-07-30 15:51:27 回复(0)
Array.prototype.slice.call(arguments)
发表于 2021-03-01 15:15:05 回复(0)
function callIt(fn) {
    var ary = [].slice.call(arguments,1)
    return fn.apply(null,ary)
}

我不明白为什么上面的可以,下面的就不行
function callIt(fn) {
    [].shift.call(arguments)
    var ary = [].slice.call(arguments)
    return fn.apply(null,ary)
}


发表于 2020-02-17 21:44:07 回复(0)
function callIt(fn) {
    return fn.apply(null, Array.prototype.slice.call(arguments, 1));
}

function callIt(fn) {
    return fn.apply(null, [].slice.call(arguments, 1));
}

发表于 2019-08-12 18:57:11 回复(0)
function callIt(fn) {
    var arr = new Array();
    for(var i = 1;i<arguments.length;i++){
        arr.push(arguments[i]);
    }
    return fn.apply(this,arr);
}

发表于 2019-08-10 12:02:12 回复(0)
        function callIt(fn) {
            var arr = Array.prototype.slice.call(arguments,1);
            return fn.apply(this, arr);
        }

发表于 2016-11-17 21:21:49 回复(0)
要注意arguments本身不存在slice方法,需要借用Array.prototype.slice进行类数组到数组的转换
function callIt(fn) {
   var args= Array.prototype.slice.call(arguments,1);
   return fn.apply(null,args);
}

发表于 2016-08-06 10:52:02 回复(0)
arguments并不是真正的数组,不能直接传入apply做参数,需要将其转换为真正的数组
发表于 2016-07-15 20:50:47 回复(0)
 function callIt(fn) {
var arr = [];
for(var i in arguments){
if(i >= 1){
arr[i-1] = arguments[i];
}
}
    return fn.apply(null,arr);
}
发表于 2016-04-06 15:57:13 回复(0)
function callIt(fn) {
    var params = Array.prototype.slice.call(arguments,1);
    return fn.apply(fn,params);
}

发表于 2015-08-25 16:02:31 回复(0)
function callIt(fn) {
    return fn.apply(this,[].slice.call(arguments,1));
}

编辑于 2015-07-14 11:46:32 回复(11)
思路:这道题的意思就是要使用apply来调用函数。那么首先声明一个数组,然后遍历数组,将其放入到新的数组args中,因为 fn 的调用参数为 callIt 的第一个参数之后的全部参数  。那么我们需要使用调用函数的方法apply()。
代码如下:
function callIt(fn) {
    var args=[];
    for(var i=1;i<arguments.length;i++){
        args.push(arguments[i]);
    }
    var result=fn.apply(null,args);
    return result;
}
发表于 2016-06-24 20:42:12 回复(8)
apply调用模式

首先介绍 apply 模式,首先这里 apply 模式既可以像函数一样使用,也可以像方法一样使用,可以说是一个灵活的使用方法。首先看看语法:函数名.apply(对象, 参数数组);

这里看语法比较晦涩,还是使用案例来说明:

1、新建两个 js 文件,分别为”js1.js”与”js2.js”;

2、添加代码

复制代码 代码如下:

// js1.js 文件中
var func1 = function() {
    this.name = "程序员";
};
func1.apply(null);
alert(name);


// js2.js 文件
var func2 = function() {
    this.name = "程序员";
};
var o = {};
func2.apply(o);
alert(o.name);


3、分别运行着两段代码,可以发现第一个文件中的 name 属性已经加载到全局对象 window 中; 而第二个文件中的 name 属性是在传入的对象 o 中,即第一个相当于函数调用,第二个相当 于方法调用。

这里的参数是方法本身所带的参数,但是需要用数组的形式存储在,比如代码:

复制代码 代码如下:

// 一个数组的例子
var arr1 = [1,2,3,[4,5],[6,7,8]];
// 将其展开
var arr2 = arr1.conact.apply([], arr1);
然后介绍一下 call 模式,call 模式与 apply 模式最大的不同在于 call 中的参数不用数组,看下面代码就清楚了:


// 定义方法
var func = function(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
};
// 创建对象
var o = {};
// 给对象添加成员
// apply 模式
var p1 = func.apply(o, ["赵晓虎", 19, "男"]);
// call 模式
var p2 = func.call(o, "赵晓虎", 19, "男");


上面的代码,apply 模式与 call 模式的结果是一样的。

实际上,使用 apply 模式和 call 模式,可以任意的操作控制 this 的意义,在函数 js 的设 计模式中使用广泛。简单小结一下,js 中的函数调用有四种模式,分别是:函数式、方法式、构造 器式和 apply 式. 而这些模式中,this 的含义分别为:在函数中 this 是全局对象 window,在方 法中 this 指当前对象,在构造函数中 this 是被创建的对象,在 apply 模式中 this 可以随意的指定.。在 apply 模式中如果使用 null,就是函数模式,如果使用对象,就是方法模式。

发表于 2016-12-05 23:34:32 回复(2)