ECMAScript 6 函数默认参数详解

作者:拾光时间:2026-10-29 10:59:42浏览:603

本文介绍ES6引入的函数默认参数特性,通过对比ES5写法展示其简化代码的优势。详细解析默认参数的定义位置、与undefined和null的区别、对函数length属性的影响,以及利用默认参数执行函数调用的高级技巧。

语言在每次更新时引入的新特性,均源于大量开发者的实际需求。规范的采纳旨在降低开发难度并提升效率。

ES5与ES6默认参数写法对比

我们通常会采用以下写法:


function calc(x, y) {
  x = x || 0;
  y = y || 0;
  // to do with x, y
  // return x/y
}

简单来说,变量x和y被赋予了默认值0。当未传递参数时,x和y以0参与运算;若传递了具体值,则使用实际传入的值进行计算。

再比如定义一个ajax请求函数:


function ajax(url, async, dataType) {
  async = async !== false
  dataType = dataType || 'JSON'
  // ...
}

这是一个使用原生JavaScript封装的简易ajax函数。其中url为必填参数,async和dataType为可选参数。若不指定async,默认发起同步请求;若不指定dataType,默认返回JSON格式数据。

又如定义一个矩形类:


function Rectangle(width, height) {
  this.width = width || 200;
  this.height = height || 300;
}

在实例化时如果不传递任何参数,系统会自动创建一个宽高分别为200和300的默认矩形对象。

无论是calc函数、ajax函数还是Rectangle类,在ES5中都需要在函数内部手动处理默认值。如果语言层面能直接支持该功能,将更为便捷。ES6引入了默认参数(Default Parameters)特性,以下是使用ES6新特性重写的calc、ajax和Rectangle示例。


function calc(x=0, y=0) {
  // ...
  console.log(x, y)
}
calc(); // 0 0
calc(1, 4); // 1 4
 
function ajax(url, async=true, dataType="JSON") {
  // ...
  console.log(url, async, dataType)
}
ajax('../user.action'); // ../user.action true JSON
ajax('../user.action', false); // ../user.action false JSON
ajax('../user.action', false, 'XML'); // ../user.action false XML
 
function Rectangle(width=200, height=300) {
  this.width = width;
  this.height = height;
}
var r1 = new Rectangle(); // 200*300的矩形
var r2 = new Rectangle(100); // 100*300的矩形
var r3 = new Rectangle(100, 500); // 100*500矩形

可以看出,ES6将默认值的定义从函数体内部移到了参数列表的小括号中,同时减少了“||”逻辑或运算的使用,使函数体更加简洁。参数默认值本就该在定义参数的地方指定,这样写法更加清晰直观。

默认参数的定义位置与注意事项

默认参数可以定义在参数列表的任意位置,例如定义在中间:


function ajax(url, async=true, success) {
  // ...
  console.log(url, async, success)
}

这里定义了一个默认参数async,而url和success为必传参数。此时,若需使用默认值,必须将中间的参数显式置为undefined。


ajax('../user.action', undefined, function() {
   
})

需要注意的是,不要想当然地将undefined替换为null。尽管在松散相等比较中null == undefined成立,但如果传入null,函数体内的async变量值将为null而非true。

默认参数的特性与高级用法

使用默认参数时需注意以下几点:

1. 定义了默认参数后,函数的length属性会减少。length属性计算的是没有默认值的参数个数,即包含默认值的参数不计入length。


function calc(x=0, y=0) {
  // ...
  console.log(x, y)
}
function ajax(url, async=true, dataType="JSON") {
  // ...
  console.log(url, async, dataType)
}
console.log(calc.length); // 0
console.log(ajax.length); // 1

2. 在函数体内,不能使用let和const再次声明具有默认值的参数,但可以使用var。


function ajax(url="../user.action", async=true, success) {
  var url = ''; // 允许
  let async = 3; // 报错
  const success = function(){}; // 报错
}

另外有一个有趣的特性:默认参数不仅可以是值类型,还可以是一个函数调用。


function getCallback() {
  return function() {
    // return code
  }
}
 
function ajax(url, async, success=getCallback()) {
  // ...
  console.log(url, async, success)
}

在此示例中,参数success被赋予了一个函数调用。当调用ajax时若未传递第三个参数,系统将执行getCallback函数,该函数返回一个新函数并赋值给success。这一功能强大,为程序员提供了广阔的发挥空间。

例如,利用这一特性可以强制要求某个参数必须传递,若不传则抛出错误。


function throwIf() {
  throw new Error('少传了参数');
}
 
function ajax(url=throwIf(), async=true, success) {
  return url;
}
ajax(); // Error: 少传了参数

以上内容即为本文的全部讲解,希望能对大家有所帮助。

作者最新文章