We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在ES5中,人们更希望函数被改进的功能是:
function foo(a = 1, b = 2) { return a + b } foo() // 3 foo(2) // 4 foo(undefined, 1) // 2
注意最后的foo(undefined, 1),第一个参数传入undefined,如果参数a有默认值的话,使用默认值。
foo(undefined, 1)
undefined
a
参数可以访问后定义的参数。但是要注意的是,这里的参数类似let,存在临时死区。如果访问的变量没有被初始化,那么就会报错。
let
function foo(a = b, b = 2) { return a + b } foo(1, 1) // 2 foo(undefined, 1) // 报错
要注意调用函数时,对应参数位置传入undefined意味着跳过这个参数,如果该参数设置了默认值的话,就会把默认值当做实际的参数,所以foo(undefined, 1)意味着跳过了参数a赋值,a就会把b当做默认值, 但是此时b还没有完成初始化,是不可访问的状态,所以这里会报错。
b
上面都是讲的命名参数, 而对于无命名参数,在ES5中是通过arguments对象处理的,ES6中有了新的方法去处理无命名参数。
arguments
在定义参数的时候,使用三个点后面跟一个名字表示不定参数,该参数为一个数组,包含了自它之后所有传入的参数。
function foo(a, ...args) { console。log(args[0]) } console。log(1, 2) // 2
不同于arguments,不定参数是一个数组。需要注意的是,不定参数必须放在最后,否则会报错,与此同时,ES6中也是可以使用arguments的。
Function
在ES5中,Function增强函数如下:
new Function([arg1 [, arg2 [, 。。。argN]] ,] functionBody)
在ES6中,可以使用默认参数和不定参数
const foo = new Function('a','b = a', 'return a + b') const bar = new Function('。。。args', 'console。log(args[0])')
当函数允许多个参数的时候, 如果方便的把多个参数呢?在ES6中,提供了展开运算符。
ES5有一个传入多个参数技巧:
let values = [1, 2, 3, 4] Math。max。apply(Math, values) // 借用了apply方法可以传入的数组的特性
上面的代码在ES6中,可以这样写:
let values = [1, 2, 3, 4] Math。max(。。。values) // 4 Math。max(。。。values, 5) // 5, 展开运算符后面可以继续跟参数
在ES5中, 函数的name值是函数的名字,在ES6中由于多了几种情况,所以name的值就有了一些增强
var doSomeThing = function doSomethingElse() { // 空函数 } var person = { get firstName() { return 'abc' } sayName() { console。log(this。name) } } var foo = function () {} console。log(doSomeThing。name) // doSomethingElse console。log(person。sayName。name) // sayName console。log(person。firstName。name) // get firstName console。log(foo。bind()。name) // bound foo console。log((new Function())。name); // anonymous
name会返回函数的name加上前缀,如getter函数会返回get XXX。需要注意的是name属性,不一定是引用的同名变量,所以不能通过name值来反向获取变量。
getter
get XXX
new。target主要是用来判断当前对象是否是通过new构造出来的。在es5中,要判断是否是new出来的,通常是用instanceof来判断,不过这样的判断是可以绕过的。
new
instanceof
function Person() { if (this instanceof Person) { console。log('是通过new构造出来的') } else { throw new Error('不是通过new构造的') } } var p1 = new Person() // 提示正确 var p2 = Person。call(p1) // 提示正确,实际是错误的
那么在ES6中,怎么使用new。target呢?当调用new的时候,new。target赋值为new操作的目标,否则值为undefined
new。target
function Person() { if (typeof new。target !== 'undefined' ) { console。log('是通过new构造出来的') } else { throw new Error('不是通过new构造的') } } var p1 = new Person() // 提示正确 var p2 = Person。call(p1) // 报错
new。target是函数的元属性(Metaproperty),要注意的是,这个理的new虽然后面跟着。,但是它不是对象。 new。target指向被new调用的构造函数,所以"new。"成为了一个虚拟上下文。在箭头函数中中,new。target 指向最近的外层函数的new。target
。
在规范里,在块级内声明函数是错误的,但是很多浏览器支持这样的操作。所以在ES5的严格模式中,如果这做会报错。
"use strict"; if(true) { function foo() { } }
但是在ES6的严格模式中,会被认为是一个块级声明,只可以在代码快中访问使用这个函数
"use strict"; if(true) { function foo() { } } console。log(foo)
在ES6的非严格模式下,块级函数不会起作用,也就是和ES5的非严格模式一样的。代码块中的声明的函数会被提升到外部或者全局
与正常的函数相比,箭头函数主要区别是:
1。 没有this、super、arguments和new。target绑定,这些值都是由最近的外层决定的 2。 不能通过new创建 3。 没有原型 4。 不可以使用this绑定 5。 不支持arguments对象 6。 不支持重复命名参数(?)
之所以有上面的这些限制,主要是因为设计箭头函数出发点是确定this的绑定,所以要把以上会干扰this绑定的因素排除掉。这样可以使得引擎更好的优化执行过程。
返回一个对象
```javascript let foo = id => ({a: id, b:2}) ```
ECMAScript6缩减了严格模式下尾调用栈的大小(非严格模式下不受影响),如果满足以下条件,尾调用不再创建新的栈帧,而是清除并重用当前栈帧:
1。 尾调用不访问当前战帧的变量(也就是说函数不是 一个闭包〉。 2。 在函数内部,尾调用是最后一条语句。 3。 尾调用的结果作为函数值返回。
下面的都不会优化,因为没有直接把函数调用作为最后的返回
"use strict" function doSomething() { // 会优化 return doSomethingElse(); } function doSomething() { // 不会优化 doSomethingElse(); } function doSomething() { // 不会优化 return 1 + doSomethingElse(); } function doSomething() { // 不会优化 return 1 + doSomethingElse(); } function doSomething() { // 不会优化 let result = doSomethingElse(); return result }
如果里面=包含闭包,也是不能优化的
function doSomething() { var num = 1, func = () => num // 包含闭包,不能优化 return func }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
参数
在ES5中,人们更希望函数被改进的功能是:
参数默认值
参数临时死区
参数可以访问后定义的参数。但是要注意的是,这里的参数类似
let
,存在临时死区。如果访问的变量没有被初始化,那么就会报错。要注意调用函数时,对应参数位置传入
undefined
意味着跳过这个参数,如果该参数设置了默认值的话,就会把默认值当做实际的参数,所以foo(undefined, 1)
意味着跳过了参数a
赋值,a
就会把b
当做默认值, 但是此时b
还没有完成初始化,是不可访问的状态,所以这里会报错。无命名参数
上面都是讲的命名参数, 而对于无命名参数,在ES5中是通过
arguments
对象处理的,ES6中有了新的方法去处理无命名参数。不定参数
在定义参数的时候,使用三个点后面跟一个名字表示不定参数,该参数为一个数组,包含了自它之后所有传入的参数。
增强
Function
构造函数在ES5中,Function增强函数如下:
在ES6中,可以使用默认参数和不定参数
展开运算符
当函数允许多个参数的时候, 如果方便的把多个参数呢?在ES6中,提供了展开运算符。
ES5有一个传入多个参数技巧:
上面的代码在ES6中,可以这样写:
name属性
在ES5中, 函数的name值是函数的名字,在ES6中由于多了几种情况,所以name的值就有了一些增强
name会返回函数的name加上前缀,如
getter
函数会返回get XXX
。需要注意的是name属性,不一定是引用的同名变量,所以不能通过name值来反向获取变量。元属性(Metaproperty) new.target
new。target主要是用来判断当前对象是否是通过
new
构造出来的。在es5中,要判断是否是new
出来的,通常是用instanceof
来判断,不过这样的判断是可以绕过的。那么在ES6中,怎么使用
new。target
呢?当调用new
的时候,new。target
赋值为new操作的目标,否则值为undefined块级函数(有疑问)
在规范里,在块级内声明函数是错误的,但是很多浏览器支持这样的操作。所以在ES5的严格模式中,如果这做会报错。
但是在ES6的严格模式中,会被认为是一个块级声明,只可以在代码快中访问使用这个函数
箭头函数
与正常的函数相比,箭头函数主要区别是:
1。 没有this、super、arguments和new。target绑定,这些值都是由最近的外层决定的
2。 不能通过new创建
3。 没有原型
4。 不可以使用this绑定
5。 不支持arguments对象
6。 不支持重复命名参数(?)
之所以有上面的这些限制,主要是因为设计箭头函数出发点是确定this的绑定,所以要把以上会干扰this绑定的因素排除掉。这样可以使得引擎更好的优化执行过程。
返回一个对象
尾递归优化
ECMAScript6缩减了严格模式下尾调用栈的大小(非严格模式下不受影响),如果满足以下条件,尾调用不再创建新的栈帧,而是清除并重用当前栈帧:
1。 尾调用不访问当前战帧的变量(也就是说函数不是 一个闭包〉。
2。 在函数内部,尾调用是最后一条语句。
3。 尾调用的结果作为函数值返回。
下面的都不会优化,因为没有直接把函数调用作为最后的返回
如果里面=包含闭包,也是不能优化的
The text was updated successfully, but these errors were encountered: