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

ES6标准---【四】【学习ES6标准看这一篇就够了!!!】

目录

ES6以往文章

rest参数

注意事项

函数的name属性

函数参数的尾逗号

Function.prototype.toString()

catch命令的参数省略

尾调用优化

什么是尾调用?

尾调用优化

尾递归

递归函数的改写

 方法一:

方法二:

ES6以往文章

ES6标准---【一】【学习ES6看这一篇就够了!!】-CSDN博客

ES6标准---【二】【学习ES6看这一篇就够了!!】-CSDN博客

ES6标准---【三】【学习ES6看这一篇就够了!!!】-CSDN博客

rest参数

RES6引入rest参数(形式为“...变量名”),用于获取函数解构赋值多余参数,这样就不需要引入“arguments”对象了

rest参数搭配的变量是一个数组,该变量将多余的参数传入数组

function add(...values) {let sum = 0;for (var val of values) {sum += val;}return sum;
}
add(2, 5, 3) // 10

注意事项

rest参数之后不能再有其它参数(即只能是最后一个参数),否则会报错

// 报错
function f(a, ...b, c) {// ...
}

函数的.length属性,不包括 rest 参数

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

函数的name属性

函数的name属性,返回该函数的函数名

function foo() {}
foo.name // "foo"

如果将一个匿名函数赋值给一个变量,ES5name属性会返回空字符串,而ES6name属性会返回变量名

var f = function () {};
// ES5
f.name // ""
// ES6
f.name // "f"

但如果给这个匿名函数赋一个具体的名字,则ES5、ES6的name属性都会返回这个具名函数原本的名字

const bar = function baz() {};
// ES5
bar.name // "baz"
// ES6
bar.name // "baz"

函数参数的尾逗号

ES6允许函数的最后一个参数有“尾逗号

  • 定义某个函数的参数时,可以有尾逗号
  • 调用某个函数填写参数时,可以有尾逗号
function clownsEverywhere(param1,param2,
) { /* ... */ }
clownsEverywhere('foo','bar',
);

Function.prototype.toString()

ES6之前的toString()方法返回函数代码本身,会省略注释空格

function /* foo comment */ foo () {}
foo.toString()
// function foo() {}

修改后的toString()方法,明确要求返回一模一样的原始代码:

<body><script>function /* 代码注释1111 */ foo () {}console.log(foo.toString())</script>	
</body>

效果

catch命令的参数省略

ES6以前,JavaScript的“try...catch”结构,明确要求catch命令后面必须跟参数,接收try代码块抛出的错误对象

try {// ...
} catch (err) {// 处理错误
}

ES6中,catch语句允许省略参数

try {// ...
} catch {// ...
}

尾调用优化

什么是尾调用?

尾调用是函数式编程的一个重要概念,是指某个函数的最后一步是调用另一个函数(递归的特殊情况)

尾调用只在严格模式下开启,正常模式是无效的

function f(x){return g(x);
}

下面三种情况都不属于“尾调用”:

// 情况一
function f(x){let y = g(x);return y;
}
// 情况二
function f(x){return g(x) + 1;
}
// 情况三
function f(x){g(x);
}

情况一:调用函数g之后,还有赋值操作,所以不属于尾调用

情况二:调用函数g之后,还有一个加法操作,所以不属于尾调用

情况三:等同于下面代码:

function f(x){g(x);return undefined;
}

尾调用不一定出现在函数尾部,只要是最后一步操作即可:

function f(x) {if (x > 0) {return m(x)}return n(x);
}

上面代码中,函数m函数n都属于尾调用,因为它们都是函数f的最后一步调用

尾调用优化

尾调用的特殊点是:“它特殊的调用位置

函数调用会在内存形成一个“调用记录”,又称“调用帧”,保存调用位置内部变量等信息

如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧

等到函数B运行结束,将结果返回给A,A的调用帧才会消失

如果函数B内部还调用函数C,那就还有一个C的调用帧

所有的调用帧共同组成了“调用栈”(call back)

  • 尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用不到了,只要内层函数的调用帧,取代外层函数的调用帧即可
function f() {let m = 1;let n = 2;return g(m + n);
}
f();
// 等同于
function f() {return g(3);
}
f();
// 等同于
g(3);

只保留了g(3)的调用帧,这就叫做“尾调用优化

注意:

  • 只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化
function addOne(a){var one = 1;function inner(b){return b + one;}return inner(a);
}

上述代码就没有办法进去“尾调用优化”,因为内层函数inner调用了外层函数的内部变量one

尾递归

函数调用自身,称为递归,如果尾调用自身,就称为尾递归

地柜非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出

但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出

一般求阶乘的递归改为尾递归求阶乘

function factorial(n) {if (n === 1) return 1;return n * factorial(n - 1);
}
factorial(5) // 120

改为:

function factorial(n, total) {if (n === 1) return total;return factorial(n - 1, n * total);
}
factorial(5, 1) // 120

递归函数的改写

实现尾递归有两种方法

  1. 可以把所有用到的内部变量改写成函数的参数
  2. 利用函数默认值

 方法一:

function tailFactorial(n, total) {if (n === 1) return total;return tailFactorial(n - 1, n * total);
}
function factorial(n) {return tailFactorial(n, 1);
}
factorial(5) // 120

方法二:

function factorial(n, total = 1) {if (n === 1) return total;return factorial(n - 1, n * total);
}
factorial(5) // 120


http://www.mrgr.cn/news/24443.html

相关文章:

  • 线性规划优化:单纯形法
  • 四款音频剪辑软件免费使用,你更pick哪一个?
  • 会话好友区设计与开发(一)
  • docker镜像下载代理
  • linux ubuntu编译 openjdk11
  • 揭秘谷歌七年AI机器人研发之路
  • 小程序——生命周期
  • 哪些旋转机械会用到本特利振动传感器
  • Assignment
  • Meme“淘金”热潮下:Meme发射平台的安全风险分析
  • 果蔬识别系统性能优化之路(一)
  • appium server gui详细按照步骤
  • Mongodb Error: queryTxt ETIMEOUT xxxx.wwwdz.mongodb.net
  • word文档的读入(5)
  • 转行人员想做网络安全工程师有哪些要求?
  • 基于SpringBoot+Vue+MySQL的志愿服务管理系统
  • [SDOI2010] 地精部落(简单dp)
  • 多个时间序列的滞后相关性
  • JAVA学习-练习试用Java实现“最小覆盖子串”
  • 东土科技加码芯片业务投资,携手神经元共建新型工业生态