重读《深入理解ES6》—— 函数
栏目: JavaScript · 发布时间: 5年前
内容简介:在 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》 —— 块级作用域
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。