摘要:箭头函数没有绑定,意味着箭头函数内部的值只能通过查找作用域链来确定。无论此后箭头函数在何处执行,该对象都是可用的。
箭头函数
es6的箭头函数,顾名思义箭头函数是使用一个箭头( => )来定义的函数,这很容易理解但是它有很多行为与传统的js函数不同:
没有 this 、 super 、 arguments 。
不能被使用 new 调用: 箭头函数没有 [[Construct]] 方法,因此不能被用为构造函数,使用 new 调用箭头函数会抛出错误。
没有原型: 既然不能对箭头函数使用 new ,那么它也不需要原型,也就是没有prototype 属性。
不能更改 this : this 的值在函数内部不能被修改,在函数的整个生命周期内其值会保持不变。
没有 arguments 对象: 既然箭头函数没有 arguments 绑定,你必须依赖于具名参数或剩余参数来访问函数的参数
不允许重复的具名参数: 箭头函数不允许拥有重复的具名参数,无论是否在严格模式下;而相对来说,传统函数只有在严格模式下才禁止这种重复
箭头函数的语法var reflect = value => value; // 有效等价于: var reflect = function(value) { return value; };
函数需要传入多个参数:
var sum = (num1, num2) => num1 + num2; // 有效等价于: var sum = function(num1, num2) { return num1 + num2; };
如果函数没有任何参数,那么在声明时就必须使用一对空括号,就像这样:
var getName = () => "Nicholas"; // 有效等价于: var getName = function() { return "Nicholas"; };
你基本可以将花括号内部的代码当做传统函数那样对待,除了 arguments 对象不可用之外。
若你想创建一个空函数,就必须使用空的花括号,就像这样:
var doNothing = () => {}; // 有效等价于: var doNothing = function() {};
花括号被用于表示函数的主体,它在你至今看到的例子中都工作正常。但若箭头函数想要从
函数体内向外返回一个对象字面量,就必须将该字面量包裹在圆括号内,例如:
var getTempItem = id => ({ id: id, name: "Temp" }); // 有效等价于: var getTempItem = function(id) { return { id: id, name: "Temp" }; };没有this绑定
JS 最常见的错误领域之一就是在函数内的 this 绑定。由于一个函数内部的 this 值可以
被改变,这取决于调用该函数时的上下文,因此完全可能错误地影响了一个对象,尽管你本
意是要修改另一个对象。
箭头函数没有 this 绑定,意味着箭头函数内部的 this 值只能通过查找作用域链来确定。
如果箭头函数被包含在一个非箭头函数内,那么 this 值就会与该函数的相等;否则,
this 值就会是全局对象(在浏览器中是 window ,在 nodejs 中是 global )。
尽管箭头函数没有自己的 arguments 对象,但仍然能访问包含它的函数的 arguments 对
象。无论此后箭头函数在何处执行,该对象都是可用的。例如:
function createArrowFunctionReturningFirstArg() { return () => arguments[0]; } var arrowFunction = createArrowFunctionReturningFirstArg(5); console.log(arrowFunction()); // 5也像对其他函数那样,你仍然可以对箭头函数使用 call() 、 apply() 与 bind() 方法,虽
然函数的 this 绑定并不会受影响。这里有几个例子:
var sum = (num1, num2) => num1 + num2; console.log(sum.call(null, 1, 2)); // 3 console.log(sum.apply(null, [1, 2])); // 3 var boundSum = sum.bind(null, 1, 2); console.log(boundSum()); // 3尾调用优化
在 ES6 中对函数最有趣的改动或许就是一项引擎优化,它改变了尾部调用的系统。尾调用(
tail call )指的是调用函数的语句是另一个函数的最后语句,就像这样:
function doSomething() { return doSomethingElse(); // 尾调用 }
在 ES5 引擎中实现的尾调用,其处理就像其他函数调用一样:一个新的栈帧( stack frame
)被创建并推到调用栈之上,用于表示该次函数调用。这意味着之前每个栈帧都被保留在内
存中,当调用栈太大时会出问题。
那什么时候不会被优化呢/
一个小改动——不返回结果(缺少return),就会产生一个无法被优化的函数:
"use strict"; function doSomething() { // 未被优化:缺少 return doSomethingElse(); }
如果你的函数在尾调用返回结果之后进行了额外操作,那么该函数也无法被优化:
"use strict"; function doSomething() { // 未被优化:在返回之后还要执行加法 return 1 + doSomethingElse(); }
关闭优化的另一个常见方式,是将函数调用的结果储存在一个变量上,之后才返回了结果,就像这样:
"use strict"; function doSomething() { // 未被优化:调用并不在尾部 var result = doSomethingElse(); return result; }
本例之所以不能被优化,是因为 doSomethingElse() 的值并没有立即被返回。
使用闭包或许就是需要避免的最困难情况,因为闭包能够访问上层作用域的变量,会导致尾调用优化被关闭。例如:
"use strict"; function doSomething() { var num = 1, func = () => num; // 未被优化:此函数是闭包 return func(); }
"use strict";
function doSomething() {
var num = 1,
func = () => num;
// 未被优化:此函数是闭包
return func();
}
此例中闭包 func() 需要访问局部变量 num ,虽然调用 func() 后立即返回了其结果,但 是对于 num 的引用导致优化不会发生.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109291.html
摘要:特性介绍箭头函数是新增的特性之一,它为这门语言提供了一种全新的书写函数的语法。用生成的函数会定义一个自己的,而箭头函数没有自己的,而是会和上一层的作用域共享。 本文同步自我得博客:http://www.joeray61.com JS中的箭头 箭头在JS里并不算是个新鲜的玩意儿,一直以来,JS都支持-->这样的箭头。 很早的时候有些浏览器还不支持JS,当时的人们为了兼容这些浏览器,需要这...
摘要:回顾我们先来回顾下箭头函数的基本语法。主要区别包括没有箭头函数没有,所以需要通过查找作用域链来确定的值。箭头函数并没有方法,不能被用作构造函数,如果通过的方式调用,会报错。 回顾 我们先来回顾下箭头函数的基本语法。 ES6 增加了箭头函数: let func = value => value; 相当于: let func = function (value) { return ...
摘要:使用或调用由于已经在词法层面完成了绑定,通过或方法调用一个函数时,只是传入了参数而已,对并没有什么影响箭头函数不会在其内部暴露出参数等等,都不会指向箭头函数的,而是指向了箭头函数所在作用域的一个名为的值如果有的话,否则,就是。 ES6之箭头函数 标签(空格分隔): 未分类 返回值 单行函数体默认返回改行计算结果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或调用由于已经在词法层面完成了绑定,通过或方法调用一个函数时,只是传入了参数而已,对并没有什么影响箭头函数不会在其内部暴露出参数等等,都不会指向箭头函数的,而是指向了箭头函数所在作用域的一个名为的值如果有的话,否则,就是。 ES6之箭头函数 标签(空格分隔): 未分类 返回值 单行函数体默认返回改行计算结果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或调用由于已经在词法层面完成了绑定,通过或方法调用一个函数时,只是传入了参数而已,对并没有什么影响箭头函数不会在其内部暴露出参数等等,都不会指向箭头函数的,而是指向了箭头函数所在作用域的一个名为的值如果有的话,否则,就是。 ES6之箭头函数 标签(空格分隔): 未分类 返回值 单行函数体默认返回改行计算结果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
阅读 3095·2021-02-22 17:12
阅读 718·2019-08-30 15:55
阅读 3077·2019-08-30 15:54
阅读 1383·2019-08-29 16:56
阅读 1861·2019-08-29 15:13
阅读 1715·2019-08-29 13:19
阅读 600·2019-08-26 13:40
阅读 2820·2019-08-26 10:26