@hotlp
2017-12-16T06:07:45.000000Z
字数 4145
阅读 749
培训文档
1.默认值
之前我们写函数时如果要制定默认值要这样:
function foo(x,y){
if (typeof y === 'undefined') {
y = 'bar';
}
...
}
在es6中,我们可以这样:
function foo(x,y='bar'){
...
// 但是 因为y被默认声明了,所以function里不能再用let,const
let y = 1; // error
const y = 2; // error
}
甚至可以与解构结合使用:
function foo({x,y='bar'}){
...
}
// 这样写再使用的时候必须传参,只有当函数foo的参数是一个对象时,变量x和y才会通过解构赋值生成
foo({});
所以我们可以解构复制默认值和参数默认值一起用:
function foo({x,y='bar'} = {}){
...
}
有默认值的参数最好放在最后,如果放在前面,那么使用默认值的时候就要传undefined:
function foo(x='bar',y){
}
foo(undefined,'hahaha') // 要这样用
2.rest参数
rest n. 剩余部分
用来获取函数的多余参数,这样就不用使用arguments这个伪数组了,而是一个真·数组:
function add(...nums){
console.log( nums instanceof Array) // true
// Array.prototype.slice.call(arguments)
let sum = 0;
for (var val of nums) {
sum += val;
}
return sum;
}
需要注意的是rest参数只能是最后一个参数,不能这样:
function foo(x,...nums,y){
}
3.箭头函数
箭头函数是一个匿名函数,并且简化了函数的定义,先看一个例子:
function oldAdd(x,y){
return x+y
}
var sum = oldAdd(1,2);
var newAdd = (x,y) => x+y
var sum = newAdd(1,2)
参数的传递和原来完全一样,rest参数什么的也能继续使用,=>
替换了原来的{}
和return
(当然这只是在返回值只有一条语句的时候,多条语句还是要加{}
和return
),如果返回值是一个对象的话还要加上()
:
var foo = () => ({name:'张三',age:'13'})
但是箭头函数并不等于匿名函数,在使用时也有很多注意事项:
1.箭头函数函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
2.不能用作构造函数
3.没有arguments对象,用rest参数代替
在写比较复杂的函数时还是建议使用原有的方式而不是箭头函数
Set和Map是ES6新增的两种数据结构,与ES5对应一下的话,Set类似于数组,Map类似于对象。
Set更像是一个没有重复元素的数组:
const set = new Set([1, 1, 2, 2, 3, 3, 4, 4]);
console.log(set)// {1,2,3,4}
但是没有数组中的方法,而是一些新增的方法:
add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
has(value):返回一个布尔值,表示该值是否为Set的成员。
clear():清除所有成员,没有返回值。
// 遍历
keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
在ES5中,数组去重是什么样的?
// 百度了一个号称最简单数组去重法
function unique1(array){
var n = [];
for(var i = 0; i < array.length; i++){
if (n.indexOf(array[i]) == -1) n.push(array[i]);
}
return n;
}
而在ES6中:
let array = [1,1,1,2,2,3,3,4,5,6,6];
[...new Set(array)] // [1, 2, 3, 4, 5, 6]
向Set中加入新值的时候,判读新旧值是否相同不会发生类型转换,类似于===
,不同的是NaN等于NaN
Object本质上是键值对的集合,键只能是字符串,而Map是一种值值对的集合:
let m = new Map();
let o = {p: 'Hello World'};
m.set(o, 'content')
m.get(o) // "content"
Map比Set多了一个属性,size
,size属性返回 Map 结构的成员总数。
新增(赋值),和取值使用set
和get
方法。
实例化时可以使用任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构当做参数,比如数组:
遍历器(Iterator)是这样一种机制:它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。比如数组,字符串,set,map等。。。
const map = new Map([
['name', '张三'],
['age', '20']
]);
map.size // 2
map.has('name') // true
map.get('name') // "张三"
map.has('age') // true
map.get('age') // "20"
class这种写法看起来更java更c++,但是之前大家早就接触过相关的用法了,不知道大家还记不记得ninjia~~(想不起来的去面壁顺便重新学一下JavaScript面向对象编程)
之前的ninjia是这样构造出来的:
function Ninjia(name, weapon) {
this.name = name;
this.weapon = weapon;
this.sayHello = function() {
console.log(this.name + '向你发射了一把' + this.weapon);
}
}
那么现在:
class Ninjia{
constructor(name, weapon) {
this.name = name;
this.weapon = weapon;
this.sayHello = function() {
console.log(this.name + '向你发射了一把' + this.weapon);
}
}
sayGoodbye(){
console.log(this.name + '拿着他的' + this.weapon+'走开了');
}
}
constructor
是类的默认方法,不写也会添加一个空方法;
在实例的时候,必须使用new,否则会报错,ES5中则不会报错;
不存在变量提升,不可以先new,再定义;
继承的写法:
class OldNinjia extends Ninjia {
constructor(name, weapon, age) {
super(name, weapon); // 调用父类的constructor(name, weapon)
this.age = age;
this.sayAge = function(){
console.log('I am ' + this.age+' years old');
}
}
}
Class 可以通过extends关键字实现继承,比起ES5的那几种继承方式看起来更直观,更好懂。继承机制也不同:
ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先创造父类的实例对象this(所以必须先调用super方法),然后再用子类的构造函数修改this。在调用super之前使用this会报错。
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
以下是几种常用的方法:
1,最基础,每次输出一个变量
// soldiers.js
export class Ninjia{
constructor(name, weapon) {
this.name = name;
this.weapon = weapon;
this.sayHello = function() {
console.log(this.name + '向你发射了一把' + this.weapon);
}
}
}
export function SwordMan{
this.name = name;
......
}
2,比较推荐,输出多个变量,很清晰
class Ninjia{
constructor(name, weapon) {
this.name = name;
this.weapon = weapon;
this.sayHello = function() {
console.log(this.name + '向你发射了一把' + this.weapon);
}
}
}
function SwordMan{
this.name = name;
......
}
export{Ninjia,swordMan}
// 或者起个别名
export{
Ninjia as N,
SwordMan as S
}
import {Ninjia, SwordMan} from './soldiers'; // 相对路径或绝对路径或模块名(需配置)
var n = new Ninjia('小花','AK-47')
// 整体加载
import * as soldier from './soldiers';
var n = new soldier.Ninjia('小花','AK-47');
// 但是不允许对soldier操作,比如:
soldier.num = 2;
// 输出时可以这样:
// helloWorld.js
export default function () {
console.log('Hello World');
}
// 用的时候这样:
import sayHello from './helloWorld';
sayHello(); // Hello World
export default输出一个叫做default的变量或方法,然后在import时你可以为随便起个名字。