您的位置:首页技术文章
文章详情页

javascript - 关于apply()与call()的问题

浏览:27日期:2023-02-23 11:40:34

问题描述

function sum(num1,num2) { return num1 + num2;}function callSum1(num1,num2) { return sum.apply(this,arguments);}function callSum2(num1,num2) { return sum.apply(this,[num1,num2]);}alert(callSum1(10,10));alert(callSum2(10,10));//call()例子就省略了

问:1.sum.apply(this,arguments)说的是对象sum调用apply方法,this指的是callSum()与sum()都是同一个作用域运行,arguments指的就是”sum1,sum2”?2.apply()与call()的在项目中应用价值是什么呢?

问题解答

回答1:

楼上写的真复杂:)

听我讲讲,题主疑惑的地方1:

function callSum1(num1,num2) { return sum.apply(this,arguments); // 这里的arguments和下面的[num1,num2]是同一个意思}function callSum2(num1,num2) { return sum.apply(this,[num1,num2]);}

arguments 是一个类似数组的对象, 对应于传递给函数的参数。arguments对象是所有函数中可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。

PS:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象

2、call和apply应用价值(存在的意义):

作用都是为了改变函数运行时上下文而存在的。 即改变函数体内部this的指向'说白点,a有xx方法,b没有。b可以问a借!'(这tm不就是继承嘛~)

call和apply不同点:

接受参数方式不一样。

如下:call接受的是连续参数,apply接受的是数组参数。A.call(this, a,b,c,d)A.apply(this, [a,b,c,d])

一个传送门:http://www.jianshu.com/p/a7b1...

回答2:

arguments是function内置属性之一,表示函数数组对象,即 callSum1里的arguments 指代 num1和num2https://developer.mozilla.org...

apply 跟 call的价值在于,能够使得指定函数里面的this指向特定的对象上,举个例子,我们用document.querySelectorAll()获取的dom其实是一个类数组对象,非数组,如果想要用数组的方法时,可以是这样

var doms = document.querySelectorAll(’p’);[].forEach.call(doms, function(e){ //遍历元素});

而apply 跟call主要区别在于参数格式,这个建议题主翻翻MDN。

回答3:

1.sum.apply(this,arguments)说的是对象sum调用apply方法,this指的是callSum()与sum()都是同一个作用域运行,arguments指的就是”sum1,sum2”?

2.apply()与call()的在项目中应用价值是什么呢?

针对 1 执行结果两个都返回 20 20

sum.apply(this,arguments) 指的是用apply来调用sum 指定sum执行的时候的this为现在的这个this 后面的arguments是参数列表 是一个类数组对象,你可以简单地当成数组对待。

sum.apply(this,[num1, num2]) 与上面类似。

关于arguments,发一张截图你可能就会有感性的认识了

javascript - 关于apply()与call()的问题

以下是针对第二点的回答

钦点this

比较好理解 就是改变 this 指向 比如在 ajax 请求的 success 回调的时候

比如在vue开发的时候 如果没有箭头函数 得要用 var that = this 这样暂存 this。 如果可以钦点this就没这些问题

举个栗子

function sayName(){ console.log(this.name); }var xiao_ming = { name: ’小明妹妹’}// 钦点 this sayName.call(xiao_ming);

javascript - 关于apply()与call()的问题

把类数组对象转化成真丶数组

arguments 通过类数组对象的形式 保存着函数的参数列表 。

function sumAll(){ var argu = Array.prototype.slice.call(arguments); // 从 0 开始积、每次 sum + cur 作为下次的 sum return argu.reduce((sum, cur) => sum + cur, 0); }

javascript - 关于apply()与call()的问题

其实从这里可以窥见:执行 slice 只需要对象具备 length 正确的下标 就可以正常执行 并返回结果。

因为数组的很多方法都可以用在类数组对象上,因此类数组对象很多时候确实可以被认为就是数组。

// 声明一个类数组对象 var a = { 0: ’hello’, 1: ’seg’, 2: ’ment’, 3: ’fault’, length: 4}// forEach Array.prototype.forEach.call(a, elem => console.log(elem)); // => 遍历打印// reduce var helloSF = Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ’ ’, ’’); console.log(helloSF); // => // 'hello seg ment fault '

javascript - 关于apply()与call()的问题

还可以做的更像数组

var a = { 0: ’hello’, 1: ’seg’, 2: ’ment’, 3: ’fault’, length: 4}a.__proto__ = Array.prototype; a.forEach(e => console.log(e)); Array.prototype.reduce.call(a, (acc, cur) => acc + cur + ’ ’, ’’);

javascript - 关于apply()与call()的问题

Object Really Like Array

实现偏函数 Partial Function

跟数学上的偏函数类似,比如:

函数 f(x, y) = x + y如果令 y = k 那么可以得到偏函数 f(x, k) = x + k ( 或者这样可能更好理解: f(x, 4) = x + 4 )

一般都是用 bind 来实现偏函数的。 不过 apply 和 call 和 bind 应该集中的讲讲。

function logger(type){ return console.log.bind(console, type); }

javascript - 关于apply()与call()的问题

用 apply 实现上述 logger 就是:

function logger2(type){ return function(){var argu = Array.prototype.slice.call(arguments); argu.unshift(type); console.log.apply(console, argu); }}

javascript - 关于apply()与call()的问题

高阶函数和柯里化

高阶函数一般指的是返回值是函数或者其参数是函数的函数。

setTimeout 是个很好的例子 它接受一个参数(一般是函数) 然后在一定时延后执行它。 不过传进去之后一般 this 就指向了 全局对象 window 如果想要钦点 this 就得用 call apply 和 bind

上面的 logger2 就做到了这点 返回了一个函数出去

关于柯里化 先看函数 add

function add(x, y){ return a + b; }add(1, 2); // => // 3

如果参数能一个一个的传 传到第二个的时候就得出结果:

var add1 = add(1); add1(2); // => 3 add(3)(4); // => 7

第一次执行返回了一个函数,如果把 add 看成是数学意义上的函数 那就是 f(x, y) = x + y 我们执行了一次 add(1) 得到 add1 其实就是令 x = 1 了,于是得到偏函数

f(1, y) = 1 + y

第二次再执行 y 会得到实际值 算式就可以算出结果出来。

这其实是一步步消元的过程。

有什么用的?

我在函数式编程方面也才初学,还没领会到精髓,唯一对柯里化体会的用处是 惰性求值 刚刚的运算在参数给齐之前不会运行 等到参数够了就会算出结果。

大半夜不睡觉刷sf 只能想到这些了。。。。

回答4:

手动设置this作用域。

回答5:

百度一下你就知道。

标签: JavaScript
相关文章: