资讯专栏INFORMATION COLUMN

JavaScript函数式编程(0):函数基础 arguments、this、apply()、cal

liuchengxu / 457人阅读

摘要:参数引用函数的上下文,函数上下文来自于等面向对象语言,中的依赖于函数声明。没有重载函数没有签名,因为其参数是由包含零或多个值的数组来表示的。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。

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())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。

当需要为函数指定上下文时,就有必要使用apply()和 call()了,一个具体的例子就是回调函数。假如对数组中的每个元素进行一次操作,命令式编程方式一般使用for循环遍历数组元素,但是函数式编程是编写一个函数,然后对每个数组元素运行该函数,区别在于函数式编程更有利于代码复用。对每个数组元素运行该函数有两种思路,一种是把数组元素作为参数传入,一种是把数组参数作为函数运行的上下文,这时就可以用到apply()和 call()。

function forEach(list, callback){
for(var n=0; n

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

4 没有重载(overloading)

ECMAScirpt函数没有签名,因为其参数是由包含零或多个值的数组来表示的。而没有函数签名,真正的重载是不可能做到的。如果在 ECMAScript 中定义了两个名字相同的函数,则该名字只属于后定义的函数。
函数重载定义:重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个运算符完成不同的运算功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/50136.html

相关文章

  • JavaScript函数编程0):函数基础 argumentsthisapply()、cal

    摘要:参数引用函数的上下文,函数上下文来自于等面向对象语言,中的依赖于函数声明。没有重载函数没有签名,因为其参数是由包含零或多个值的数组来表示的。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。 1 函数参数 函数的实参和形参个数可以不等,之所以会这样,原因是 ECMAScript 中的参数在内部是用一个数组来表示的。函数接收到的始终都是这个数组,而不关心数组中包含哪...

    陈伟 评论0 收藏0
  • JavaScript函数编程

    摘要:本文试图尽可能系统的描述函数式编程。函数式编程使用参数保存状态,最好的例子就是递归。柯里化函数有利于指定函数行为,并将现有函数组合为新函数。 JavaScript函数式编程 摘要 以往经常看到函数式编程这一名词,却始终没有花时间去学习,暑期实习结束之后一直忙于边养老边减肥,81天成功瘦身30斤+ ,开始回归正常的学习生活。便在看《JavaScript函数式编程》这本书,以系统了解函数式...

    animabear 评论0 收藏0
  • JavaScript 的继承方及优缺点

    摘要:继承简介在的中的面向对象编程,继承是给构造函数之间建立关系非常重要的方式,根据原型链的特点,其实继承就是更改原本默认的原型链,形成新的原型链的过程。 showImg(https://segmentfault.com/img/remote/1460000018998684); 阅读原文 前言 JavaScript 原本不是纯粹的 OOP 语言,因为在 ES5 规范中没有类的概念,在 ...

    nanchen2251 评论0 收藏0
  • JavaScript || 函数

    摘要:每个函数表达式包括函数对象括号和传入的实参组成。和作用都是动态改变函数体内指向,只是接受参数形式不太一样。在定义函数时,形参指定为一个对象调用函数时,将整个对象传入函数,无需关心每个属性的顺序。 函数 JavaScript中,函数指只定义一次,但可以多次被多次执行或调用的一段JavaScript代码。与数组类似,JavaScript中函数是特殊的对象,拥有自身属性和方法 每个函数对象...

    learn_shifeng 评论0 收藏0
  • 掌握JavaScript函数的柯里化

    摘要:原文链接和都支持函数的柯里化函数的柯里化还与的函数编程有很大的联系如果你感兴趣的话可以在这些方面多下功夫了解相信收获一定很多看本篇文章需要知道的一些知识点函数部分的闭包高阶函数不完全函数文章后面有对这些知识的简单解释大家可以看看什么是柯里化 原文链接 Haskell和scala都支持函数的柯里化,JavaScript函数的柯里化还与JavaScript的函数编程有很大的联系,如果你感兴...

    DTeam 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<