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()的在项目中应用价值是什么呢?
淡淡烟草味2017-07-05 11:03:57
楼上写的真复杂:)
听我讲讲,题主疑惑的地方
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...
typecho2017-07-05 11:03:57
arguments是function内置属性之一,表示函数数组对象,即 callSum1里的arguments 指代 num1和num2
https://developer.mozilla.org...
apply 跟 call的价值在于,能够使得指定函数里面的this指向特定的对象上,举个例子,我们用document.querySelectorAll()
获取的dom其实是一个类数组对象,非数组,如果想要用数组的方法时,可以是这样
var doms = document.querySelectorAll('p');
[].forEach.call(doms, function(e){
//遍历元素
});
而apply 跟call主要区别在于参数格式,这个建议题主翻翻MDN。
巴扎黑2017-07-05 11:03:57
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,发一张截图你可能就会有感性的认识了
以下是针对第二点的回答
比较好理解 就是改变 this 指向 比如在 ajax 请求的 success 回调的时候
比如在vue开发的时候 如果没有箭头函数 得要用 var that = this
这样暂存 this。 如果可以钦点this就没这些问题
举个栗子
function sayName(){
console.log(this.name);
}
var xiao_ming = {
name: '小明妹妹'
}
// 钦点 this
sayName.call(xiao_ming);
arguments 通过类数组对象的形式 保存着函数的参数列表 。
function sumAll(){
var argu = Array.prototype.slice.call(arguments);
// 从 0 开始积、每次 sum + cur 作为下次的 sum
return argu.reduce((sum, cur) => sum + cur, 0);
}
其实从这里可以窥见:执行 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 "
还可以做的更像数组
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 + ' ', '');
Object Really Like Array
跟数学上的偏函数类似,比如:
函数 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);
}
用 apply 实现上述 logger
就是:
function logger2(type){
return function(){
var argu = Array.prototype.slice.call(arguments);
argu.unshift(type);
console.log.apply(console, argu);
}
}
高阶函数一般指的是返回值是函数或者其参数是函数的函数。
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 只能想到这些了。。。。