当前位置: 首页 > news >正文

函数的扩展

文章目录

    • 函数的扩展
      • 1.函数参数的默认值
      • 1.1 基本用法
      • -- 参数变量是默认声明的,所以不能用 let或const 再次声明
      • -- 使用参数默认值时,函数不能有同名参数
      • 1.2 与解构赋值默认值结合使用
      • ☆☆☆ 函数参数的默认值生效以后,参数解构赋值依然会进行
      • 1.3 参数默认值的位置

函数的扩展

1.函数参数的默认值

1.1 基本用法

ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x, y = 'World') {  // lz:相当于是默认参数直接赋值了console.log(x, y);
}log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

可以看到,ES6 的写法比 ES5 简洁许多,而且非常自然。下面是另一个例子。

function Point(x = 0, y = 0) {  // js这个默认参数写在()中,思路很好!this.x = x;this.y = y;
}const p = new Point();
p // { x: 0, y: 0 }

除了简洁,ES6 的写法还有两个好处:首先,阅读代码的人,可以立刻意识到哪些参数是可以省略的,不用查看函数体或文档;其次,有利于将来的代码优化,即使未来的版本在对外接口中,彻底拿掉这个参数,也不会导致以前的代码无法运行。

————

– 参数变量是默认声明的,所以不能用 let或const 再次声明

function foo(x = 5) {let x = 1;  // errorconst x = 2; // error
}

————

– 使用参数默认值时,函数不能有同名参数

// 不报错,因为没有使用默认参数
function foo(x, x, y) {// ...
}// 报错
function foo(x, x, y = 1) {// ...
}
// SyntaxError: Duplicate parameter name not allowed in this context

另外,一个容易忽略的地方是,参数默认值不是传值的,而是每次都重新计算默认值表达式的值。也就是说,参数默认值是惰性求值的。

let x = 99;
function foo(p = x + 1) {console.log(p);
}foo() // 100x = 100;
foo() // 101

上面代码中,参数p的默认值是 x + 1。这时,每次调用函数 foo(),都会重新计算x + 1,而不是默认p等于 100


1.2 与解构赋值默认值结合使用

参数默认值可以与解构赋值的默认值,结合起来使用。
(讲解解构赋值的地方也涉及到函数)

function foo({x, y = 5}) {console.log(x, y);
}foo({}) // undefined 5  // 提供一个空对象作为参数,不报错
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined  // 没有提供参数用于解构赋值!所以报错!

上面代码只使用了对象的解构赋值默认值,没有使用函数参数的默认值。只有当函数foo()的参数是一个对象时,变量xy才会通过解构赋值生成。

如果函数foo()调用时没提供参数,变量xy就不会生成,从而报错。通过提供函数参数的默认值,就可以避免这种情况。

参考解构赋值:☆☆☆ 函数参数解构的默认值

// 为变量x和y指定默认值
function foo({x, y = 5} = {}) {  // 对象的默认值console.log(x, y);
}foo() // undefined 5

上面代码指定,如果没有提供参数,函数foo的参数默认为一个空对象。

————
下面是另一个解构赋值默认值的例子。

function fetch(url, { body = '', method = 'GET', headers = {} }) { console.log(method);        // 以上存在危险写法!
}fetch('http://example.com', {})
// "GET"fetch('http://example.com')
// 报错

上面代码中,如果函数fetch()的第二个参数是一个对象,就可以为它的三个属性设置默认值。

这种写法不能省略第二个参数,如果结合函数参数的默认值,就可以省略第二个参数。这时,就出现了双重默认值。

function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {console.log(method);
}fetch('http://example.com')
// "GET"

上面代码中,函数fetch没有第二个参数时,函数参数的默认值就会生效,然后才是解构赋值的默认值生效,变量method才会取到默认值GET

☆☆☆ 函数参数的默认值生效以后,参数解构赋值依然会进行

function f({ a, b = 'world' } = { a: 'hello' }) {console.log(b);
}f() // world

上面示例中,函数f()调用时没有参数,所以参数默认值{ a: 'hello' }生效,然后再对这个默认值进行解构赋值,从而触发参数变量b的默认值生效。

————
作为练习,大家可以思考一下,下面两种函数写法有什么差别?

// 写法一
function m1({x = 0, y = 0} = {}) {return [x, y];
}// 写法二
function m2({x, y} = { x: 0, y: 0 }) {return [x, y];
}// 函数没有参数的情况
m1() // [0, 0]
m2() // [0, 0]// x 和 y 都有值的情况
m1({x: 3, y: 8}) // [3, 8]
m2({x: 3, y: 8}) // [3, 8]// x 有值,y 无值的情况
m1({x: 3}) // [3, 0]
m2({x: 3}) // [3, undefined]// x 和 y 都无值的情况
m1({}) // [0, 0];
m2({}) // [undefined, undefined]m1({z: 3}) // [0, 0]
m2({z: 3}) // [undefined, undefined]

1.3 参数默认值的位置

http://www.lryc.cn/news/197512.html

相关文章:

  • Cypress安装使用
  • 怎么把图片改成jpg格式?
  • [一带一路金砖 2023 CTF]Crypto
  • FPGA【Verilog语法】
  • Flume 整合 Kafka
  • VUE:侧边弹出栏组件,组件中有树状图,搜索框可筛选树状图节点,可收缩
  • 如何使用pytorch定义一个多层感知神经网络模型——拓展到所有模型知识
  • 为什么引入SVG文件,给它定义属性不生效原理分析
  • Integer包装类常用方法和属性
  • 基于Spring boot轻松实现一个多数据源框架
  • vue前端实现打印功能并约束纸张大小---调用浏览器打印功能打印页面部分元素并固定纸张大小
  • 音乐播放器蜂鸣器ROM存储歌曲verilog,代码/视频
  • Arduino Nano 引脚复用分析
  • Go 函数多返回值错误处理与error 类型介绍
  • 数论分块
  • 宏任务与微任务,代码执行顺序
  • 正方形(Squares, ACM/ICPC World Finals 1990, UVa201)rust解法
  • 【算法设计与分析qwl】伪码——顺序检索,插入排序
  • Uniapp路由拦截-自定义路由白名单
  • 在中国可以使用 HubSpot 吗?
  • Java的基础应用
  • 【excel】列转行
  • 用Bing绘制「V我50」漫画;GPT-5业内交流笔记;LLM大佬的跳槽建议;Stable Diffusion生态全盘点第一课 | ShowMeAI日报
  • Java身份证实名认证-阿里云API 【姓名、身份证号】
  • ND协议——无状态地址自动配置 (SLAAC)
  • iOS开发UITableView的使用,区别Plain模式和Grouped模式
  • css美化滚动条
  • 【CANoe】XML Test Module使用实例
  • oracle的update语句where条件后的索引字段为空时不执行
  • RabbitMQ的特点