JavaScript定义函数_动力节点Java学院整理


Posted in Javascript onJune 27, 2017

在JavaScript中,定义函数的方式如下:

function abs(x) {
 if (x >= 0) {
  return x;
 } else {
  return -x;
 }
}

上述abs()函数的定义如下:

  • function指出这是一个函数定义;
  • abs是函数的名称;
  • (x)括号内列出函数的参数,多个参数以,分隔;
  • { ... }之间的代码是函数体,可以包含若干语句,甚至可以没有任何语句。

请注意,函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。因此,函数内部通过条件判断和循环可以实现非常复杂的逻辑。

如果没有return语句,函数执行完毕后也会返回结果,只是结果为undefined。

由于JavaScript的函数也是一个对象,上述定义的abs()函数实际上是一个函数对象,而函数名abs可以视为指向该函数的变量。

因此,第二种定义函数的方式如下:

var abs = function (x) {
  if (x >= 0) {
    return x;
  } else {
    return -x;
  }
};

在这种方式下,function (x) { ... }是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量abs,所以,通过变量abs就可以调用该函数。

上述两种定义完全等价,注意第二种方式按照完整语法需要在函数体末尾加一个;,表示赋值语句结束。

调用函数

调用函数时,按顺序传入参数即可:

abs(10); // 返回10
abs(-9); // 返回9

由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数:

abs(10, 'blablabla'); // 返回10
abs(-9, 'haha', 'hehe', null); // 返回9

传入的参数比定义的少也没有问题:

abs(); // 返回NaN

此时abs(x)函数的参数x将收到undefined,计算结果为NaN。

要避免收到undefined,可以对参数进行检查:

function abs(x) {
  if (typeof x !== 'number') {
    throw 'Not a number';
  }
  if (x >= 0) {
    return x;
  } else {
    return -x;
  }
}

arguments

JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array:

function foo(x) {
  alert(x); // 10
  for (var i=0; i<arguments.length; i++) {
    alert(arguments[i]); // 10, 20, 30
  }
}
foo(10, 20, 30);

利用arguments,你可以获得调用者传入的所有参数。也就是说,即使函数不定义任何参数,还是可以拿到参数的值:

function abs() {
  if (arguments.length === 0) {
    return 0;
  }
  var x = arguments[0];
  return x >= 0 ? x : -x;
}
abs(); // 0
abs(10); // 10
abs(-9); // 9

实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法:

// foo(a[, b], c)
// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
function foo(a, b, c) {
  if (arguments.length === 2) {
    // 实际拿到的参数是a和b,c为undefined
    c = b; // 把b赋给c
    b = null; // b变为默认值
  }
  // ...
}

要把中间的参数b变为“可选”参数,就只能通过arguments判断,然后重新调整参数并赋值。

rest参数

由于JavaScript函数允许接收任意个参数,于是我们就不得不用arguments来获取所有参数:

function foo(a, b) {
  var i, rest = [];
  if (arguments.length > 2) {
    for (i = 2; i<arguments.length; i++) {
      rest.push(arguments[i]);
    }
  }
  console.log('a = ' + a);
  console.log('b = ' + b);
  console.log(rest);
}

为了获取除了已定义参数a、b之外的参数,我们不得不用arguments,并且循环要从索引2开始以便排除前两个参数,这种写法很别扭,只是为了获得额外的rest参数,有没有更好的方法?

ES6标准引入了rest参数,上面的函数可以改写为:

function foo(a, b, ...rest) {
  console.log('a = ' + a);
  console.log('b = ' + b);
  console.log(rest);
}
foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]
foo(1);
// 结果:
// a = 1
// b = undefined
// Array []

rest参数只能写在最后,前面用...标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。

如果传入的参数连正常定义的参数都没填满,也不要紧,rest参数会接收一个空数组(注意不是undefined)。

因为rest参数是ES6新标准,所以你需要测试一下浏览器是否支持。请用rest参数编写一个sum()函数,接收任意个参数并返回它们的和:

窗体顶端

'use strict';
// 测试:
var i, args = [];
for (i=1; i<=100; i++) {
  args.push(i);
}
if (sum() !== 0) {
  alert('测试失败: sum() = ' + sum());
} else if (sum(1) !== 1) {
  alert('测试失败: sum(1) = ' + sum(1));
} else if (sum(2, 3) !== 5) {
  alert('测试失败: sum(2, 3) = ' + sum(2, 3));
} else if (sum.apply(null, args) !== 5050) {
  alert('测试失败: sum(1, 2, 3, ..., 100) = ' + sum.apply(null, args));
} else {
  alert('测试通过!');
}

小心你的return语句

前面我们讲到了JavaScript引擎有一个在行末自动添加分号的机制,这可能让你栽到return语句的一个大坑:

function foo() {
  return { name: 'foo' };
}
foo(); // { name: 'foo' }

如果把return语句拆成两行:

function foo() {
  return
    { name: 'foo' };
}
foo(); // undefined

要小心了,由于JavaScript引擎在行末自动添加分号的机制,上面的代码实际上变成了:

function foo() {
  return; // 自动添加了分号,相当于return undefined;
    { name: 'foo' }; // 这行语句已经没法执行到了
}

所以正确的多行写法是:

function foo() {
  return { // 这里不会自动加分号,因为{表示语句尚未结束
    name: 'foo'
  };
}

练习

定义一个计算圆面积的函数area_of_circle(),它有两个参数:

r: 表示圆的半径;

pi: 表示π的值,如果不传,则默认3.14

Javascript 相关文章推荐
jquery 插件 人性化的消息显示
Jan 21 Javascript
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
May 07 Javascript
jQuery实现下拉框左右选择的简单实例
Feb 22 Javascript
jquery判断浏览器后退时候弹出消息的方法
Aug 11 Javascript
WEB 前端开发中防治重复提交的实现方法
Oct 26 Javascript
JavaScript构建自己的对象示例
Nov 29 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
Dec 02 Javascript
移动端利用H5实现压缩图片上传功能
Mar 29 Javascript
详解Vue学习笔记入门篇之组件的内容分发(slot)
Jul 17 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
Aug 17 Javascript
前端面试知识点目录一览
Apr 15 Javascript
如何利用JavaScript编写一个格斗小游戏
Jan 06 Javascript
详解vue项目构建与实战
Jun 27 #Javascript
微信小程序 蓝牙的实现实例代码
Jun 27 #Javascript
微信小程序 开发MAP(地图)实例详解
Jun 27 #Javascript
微信小程序商品到详情的实现
Jun 27 #Javascript
微信小程序的分类页面制作
Jun 27 #Javascript
JS实现批量上传文件并显示进度功能
Jun 27 #Javascript
angular过滤器实现排序功能
Jun 27 #Javascript
You might like
PHP 一个比较完善的简单文件上传
2010/03/25 PHP
比较全面的PHP数组的使用方法小结
2010/09/23 PHP
解析使用substr截取UTF-8中文字符串出现乱码的问题
2013/06/20 PHP
解析wamp5下虚拟机配置文档
2013/06/27 PHP
php自动加载autoload机制示例分享
2014/02/20 PHP
ThinkPHP自动填充实现无限级分类的方法
2014/08/22 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
2016/12/06 PHP
thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法
2018/09/07 PHP
设置checkbox为只读(readOnly)的两种方式
2013/10/11 Javascript
jquery form表单序列化为对象的示例代码
2014/03/05 Javascript
HTML,CSS,JavaScript速查表推荐
2014/12/02 Javascript
javascript实现瀑布流自适应遇到的问题及解决方案
2015/01/28 Javascript
BootStrap智能表单实战系列(三)分块表单配置详解
2016/06/13 Javascript
angularJs的ng-class切换class
2017/06/23 Javascript
js实现canvas保存图片为png格式并下载到本地的方法
2017/08/31 Javascript
JS使用正则表达式获取小括号、中括号及花括号内容的方法示例
2018/06/01 Javascript
ES6 Array常用扩展的应用实例分析
2019/06/26 Javascript
JS call()及apply()方法使用实例汇总
2020/07/11 Javascript
python语言中with as的用法使用详解
2018/02/23 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
2018/09/04 Python
python 进程 进程池 进程间通信实现解析
2019/08/23 Python
python同步windows和linux文件
2019/08/29 Python
DJango的创建和使用详解(默认数据库sqlite3)
2019/11/18 Python
Python 一行代码能实现丧心病狂的功能
2020/01/18 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
python使用建议与技巧分享(一)
2020/08/17 Python
基于Python爬取搜狐证券股票过程解析
2020/11/18 Python
Tomcat Mysql datasource数据源配置
2015/12/28 面试题
2014年创先争优活动总结
2014/05/04 职场文书
乳制品整治工作方案
2014/05/29 职场文书
社区关爱留守儿童活动方案
2014/08/22 职场文书
初中毕业典礼演讲稿
2014/09/09 职场文书
还款承诺书范本
2015/01/20 职场文书
庆元旦主持词
2015/07/06 职场文书
python基础之函数的定义和调用
2021/10/24 Python
ubuntu端向日葵键盘输入卡顿问题及解决
2022/12/24 Servers