JavaScript函数式编程(0):函数基本 arguments、this、apply()、call()

1 函数参数

函数的实参和形参个数可以不等,之所以会如许,原因是 ECMAScript 中的参数在内部是用一个数组来示意的。函数吸收到的一直都是这个数组,而不关心数组中包括哪些参数(如果有参数的话)。如果实参个数大于形参个数,过剩的实参不通报值,然则在arguments中可以接见;如果形参个数大于实参,没有通报值的实参将自动被给予 undefined 值。

2 arguments和this

一切的函数挪用都邑通报两个隐式参数:arguments和this。
实际上,在函数体内可以经由过程 arguments对象来接见这个参数数组,从而猎取通报给函数的每一个参数。arguments 对象只是与数组相似(它并不是 Array 的实例),由于可以运用方括号语法接见它的每一个元素(arguments[0]、argumetns[1]…),也运用 length 属性来一定通报进来多少个参数。

arguments对象的值永久与对应定名参数的值坚持同步:

function doAdd(num1, num2) {
    arguments[1] = 10;
    alert(arguments[0] + num2);
}

由于 arguments对象中的值会自动反应到对应的定名参数,所以修正 arguments[1],也就修正了 num2,效果它们的值都邑变成 10。不过,这并不是说读取这两个值会接见雷同的内存空间;它们的内存空间是自力的,但它们的值会同步。别的还要记着,如果只传入了一个参数,那末为 arguments[1]设置的值不会反应到定名参数中(num2坚持undefined)。这是由于 arguments 对象的长度是由传入的参数个数决议的,不是由定义函数时的定名参数的个数决议的。

this参数援用函数的上下文,函数上下文来自于Java等面向对象言语,Java中的this依赖于函数声明。然则和Java差别,JavaScript中的this依赖于函数的挪用体式格局,因而把this称为挪用上下文很适宜。平常函数有四种挪用体式格局:简朴函数挪用;对象要领挪用;作为组织函数挪用;经由过程apply()和call()挪用。这四种体式格局的重要区分就在于挪用上下文差别:简朴函数挪用的上下文是window对象,要领挪用的上下文是对象,组织函数的上下文是是新创建的对象实例。这些挪用中函数的this指向都是牢固的,然则只要apply()和call()挪用可以自立定义上下文。

3 apply()/call():在特定的作用域中挪用函数。

区分在于吸收参数的体式格局差别:apply(argu1,argu2),argu1是函数运转的作用域(this),argu2是参数数组,可以传入arguments 对象或许参数数组;call(argu1,argu2), argu1是this,argu2是逐一列出的函数参数。
如果你盘算直接传入 arguments 对象,或许包括函数中先吸收到的也是一个数组,那末运用 apply()一定更轻易;不然,挑选 call()可以更适宜。(在不给函数通报参数的情况下,运用哪一个要领都无所谓。)
通报参数并不是 apply()和 call()真正的用武之地;它们真正壮大的处所是可以扩大函数赖以运转的作用域。运用 call()(或 apply())来扩大作用域的最大优点,就是对象不需要与要领有任何耦合关联。
《JavaScript函数式编程(0):函数基本 arguments、this、apply()、call()》

当需要为函数指定上下文时,就有必要运用apply()和 call()了,一个详细的例子就是回调函数。如果对数组中的每一个元素举行一次操纵,敕令式编程体式格局平常运用for轮回遍历数组元素,然则函数式编程是编写一个函数,然后对每一个数组元素运转该函数,区分在于函数式编程更有利于代码复用。对每一个数组元素运转该函数有两种思绪,一种是把数组元素作为参数传入,一种是把数组参数作为函数运转的上下文,这时候就可以用到apply()和 call()。

function forEach(list, callback){
for(var n=0; n<list.length; n++){
    callback.call(list[n], n);
    }
}
var colors = ["blue", "red","green"]; 
var res = [];
forEach(colors, function(index){
    res[index] = (this == colors[index]);
    return res;//true,true,true
});
alert(res);

运用callback回调函数的call要领,将当前数组元素作为第一个参数传入,将当前数组索引作为第二个参数传入,这使得当前元素变成函数上下文,索引值作为callback()的参数。在callback()内部考证当前元素是不是是上下文。

4 没有重载(overloading)

ECMAScirpt函数没有署名,由于其参数是由包括零或多个值的数组来示意的。而没有函数署名,真正的重载是不可以做到的。如果在 ECMAScript 中定义了两个名字雷同的函数,则该名字只属于后定义的函数。
函数重载定义:重载函数是函数的一种特殊情况,为轻易运用,C++许可在统一局限中声明几个功用相似的同名函数,然则这些同名函数的形式参数(指参数的个数、范例或许递次)必需差别,也就是说用统一个运算符完成差别的运算功用。这就是重载函数。重载函数常用来完成功用相似而所处置惩罚的数据范例差别的题目。

    原文作者:zhangding
    原文地址: https://segmentfault.com/a/1190000007124075
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞