重读《深入理解ES6》—— 函数
栏目: JavaScript · 发布时间: 6年前
内容简介:在 ES6 之前,JavaScript 的函数语法几乎没有发生太大的变化,而遗留的一些问题导致实现一些基本的功能经常要编写很多代码。而 ES6 对函数的大力度改进,让我们编写函数时更加方便且更少出错。而关于参数的处理以及箭头函数是我非常喜欢的功能。JavaScript 中的函数有一个比较特别的地方是形参和实参的数量可以不相同。当定义的形参没有默认值传入的时候,JavaScript 会为我们自动传入一个默认值。
在 ES6 之前,JavaScript 的函数语法几乎没有发生太大的变化,而遗留的一些问题导致实现一些基本的功能经常要编写很多代码。而 ES6 对函数的大力度改进,让我们编写函数时更加方便且更少出错。
而关于参数的处理以及箭头函数是我非常喜欢的功能。
一、函数形参的默认值
JavaScript 中的函数有一个比较特别的地方是形参和实参的数量可以不相同。当定义的形参没有默认值传入的时候,JavaScript 会为我们自动传入一个默认值。
在 ES5 的阶段,我们通常会自己设置一个默认值,就像下面这样:
function getAge(age) { age = age || 10; console.log(age); } getAge(12); // 12 getAge(0); // 10 复制代码
这段代码想告诉我们,当传入参数时,我们就取传入的值,如果没有传入,我们就取默认的 10。但是这通常会有一个问题,当我们传入一个 0 的时候,它也会被默认为一个假值,并最终将 age 赋值为 10。
在这种情况下,我们往往通过 typeof
检查参数类型,来实现相关功能:
function getAge(age) { age = (typeof age !== "undefined") ? age : 10; console.log(age); } getAge(12); // 12 getAge(0); // 10 复制代码
这种写法可以帮助我们更好地处理参数,但仔细想想,若是有多个参数时,这会让我们写许多额外的代码。幸好 ES6 参数默认值设置的出现,让我们可以很好的解决这个问题。
function getAge(age=10) { console.log(age); } getAge(); // 10,使用默认值 getAge(12); // 12,不使用默认值 getAge(0); // 0,不适用默认值,且传入参数为假值的情况 复制代码
值得注意的一点是:
function getAge(age=10, newAge=age) { console.log(newAge); } getAge(); // 10 复制代码
你可以把第二个参数的默认值设置为第一个参数,但是不能把第一个参数的默认值设置为第二个参数。
另一方面,函数的默认值还可以是一个表达式:
function getValue() { return 3; } function add(first, second=getValue()) { return first + second; } add(1, 3); // 4 add(2); // 5 复制代码
二、箭头函数
箭头函数是一个比较有趣的特性。因为简单的语法,大家工作中也经常用到,所以大家也比较熟悉,下面就简单说说箭头函数的语法。
箭头函数有1个参数,且函数体只有一条语句:
let f = value => value; // 相当于 let f = function(value) { return value; }; 复制代码
箭头函数没有参数或者有多个参数,参数部分需要使用小括号:
let f = () => 20; // 相当于 let f = function() { return 20 }; let f = (a, b) => a + b; // 相当于 let f = function(a, b) { return a + b; } 复制代码
箭头函数的函数体内有多条语句:
let f = (a, b) => { return a * b; }; 复制代码
想让箭头函数返回一个对象字面量,需要将该字面量包裹在小括号里:
let f = () => ({ id: 1, name: 'zhangsan', age: 18 }); // 相当于 let f = function() { return { id: 1, name: 'zhangsan', age: 18 }; } 复制代码
简单的介绍完箭头函数的基本语法,我们来看看箭头函数的一些主要特性:
1、箭头函数没有 this 绑定
箭头函数中没有 this
绑定,必须通过查找作用域链来决定其值。如果箭头函数被非箭头函数包含,则 this
绑定的是最近一层非箭头函数的 this
;否则, this
的值会被设置为全局对象。
或者再简单一点来说: 箭头函数的 this
指向离它最近的父级作用域 。
举个例子:
// 普通函数 let person = { name: 'zhangsan', age: 18, say: function() { console.log(this); // person 对象 console.log(this.name); // 'zhangsan' console.log(this.age); // 18 } }; person.say(); // 普通函数,谁调用,this 指向谁 复制代码
// 箭头函数 let person = { name: 'zhangsan', age: 18, say: () => { console.log(this); // window 对象 console.log(this.name); // undefined console.log(this.age); // undefined } }; person.say(); // 箭头函数,没有 this,函数内部的 this,指向父级作用域,即全局 复制代码
最后,因为箭头函数中没有 this
,所以也不能用 call()、apply()、bind()
等方法改变 this
的指向。
2、箭头函数没有原型,不能通过 new
来调用
箭头函数的设计初衷是”即用即弃“,所以不能用它来定义新类型。所以,箭头函数中没有 prototype
属性,自然不能实例化,也就是不能用 new
关键字来调用。
let Person = () => {}; let p1 = new Person(); // Uncaught TypeError: Person is not a constructor let Person = () => {}; console.log(Person.prototype); // undefined 复制代码
3、没有 argments 绑定
// 普通函数 let person = function() { console.log(arguments); } person(1); // 打印 arguments 对象 复制代码
// 箭头函数 let person = () => { console.log(arguments); } person(1); // Uncaught ReferenceError: arguments is not defined 复制代码
总的来说,箭头函数和一些小特性的加入,可以使我们的编码更加方便。
友情链接
如果文章中错误或表述不严谨的地方,欢迎指正
也欢迎大家关注我的同名微信公众号:李等等扣丁
以上所述就是小编给大家介绍的《重读《深入理解ES6》—— 函数》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- GFS论文重读
- APUEv3 - 重读笔记
- 重读 Redux 源码的感悟
- 重读 JVM - javac & javap
- 重读 JVM - ParNew & CMS GC
- 重读《深入理解ES6》 —— 块级作用域
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Parsing Techniques
Dick Grune、Ceriel J.H. Jacobs / Springer / 2010-2-12 / USD 109.00
This second edition of Grune and Jacobs' brilliant work presents new developments and discoveries that have been made in the field. Parsing, also referred to as syntax analysis, has been and continues......一起来看看 《Parsing Techniques》 这本书的介绍吧!