重学ES6基础语法(二)

本系列博客为ES6基础语法的使用及总结,若有错误,欢迎指正。 重学ES6基础语法(二)主要包括 默认参数值模板字符串解构赋值剩余参数扩展运算符 等。javascript

默认参数值(Default parameters)

函数默认参数容许在没有值或undefined被传入时使用默认形参。html

1.语法java

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) { 
    statements 
}
复制代码

2.使用git

2.1 在ES6以前能够经过逻辑运算符来给形参指定默认值es6

格式: 条件A || 条件Bgithub

若是条件A成立, 那么就返回条件A;web

若是条件A不成立, 不管条件B是否成立, 都会返回条件B。express

function getInfo(a, b) {
    a = a || "今天要少吃,";
    b = b || "明天也要少吃";
    console.log(a, b);
}
getInfo(); //打印默认值 --> 今天要少吃,明天也要少吃
getInfo("mss"); //至关于传递了参数a,未传参数b --> mss 明天也要少吃
getInfo(undefined,"mss"); //表示参数a是未知的,此时采用默认值 --> 今天要少吃, mss
getInfo(123, "abc"); //参数ab都是由外界传递的 --> 123 "abc"
复制代码

2.2 从ES6开始直接经过变量=指定默认值便可给形参指定默认值数组

function getInfo(a = "今天要少吃", b = ", 明天也要少吃") {
    console.log(a, b);
};
getInfo(); //今天要少吃, 明天也要少吃
getInfo(123, "abc"); //123 "abc"
复制代码

注意:① 若是只传递了一个参数,则表明第一个参数使用咱们传递进来的,其余参数仍是使用默认值。bash

② 若是须要给某一个参数指定内容,其余参数须要传递undefined

③ 问:给其余参数传递null能够吗?答:别问,问就是不能够,问就是让你本身回去试

function multiply(a = 3, b = 5) {
   return a * b;
}
console.log(multiply(5, 2)); // ab均为传递进来的值,为10
console.log(multiply(5)); // a是5,b是默认值5,结果为25
console.log(multiply(undefined,10)); //a是默认值3,b是10,结果为30

function test(a = 1,b = 2, c = 3, d = 4) {
    return a + b + c + d;
}
console.log(test(undefined, undefined, 4, undefined)); //11
复制代码

2.3 ES6中的默认值还能够从其它的函数中获取

function getSum(a = "少吃,", b = getDefault()) {
    console.log(a, b);
}
getSum();
// getSum(123, "abc");
function getDefault() {
    return "零食";
}
复制代码

模板字符串(Template literals (Template strings))

模板字面量 是容许嵌入表达式的字符串字面量。你可使用多行字符串和字符串插值功能。

1.语法

将须要插入的内容放在一对反引号``里面

模板字符串使用反引号来代替普通字符串中的用双引号和单引号。模板字符串能够包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一块儿传递给一个默认函数,该函数负责将全部的部分链接起来,若是一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式一般是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你均可以经过该函数来对模板字符串进行操做处理。在模版字符串内使用反引号(`)时,须要在它前面加转义符(\)。

`string text` //单行

`string text line 1
 string text line 2` //多行

`string text ${expression} string text` //包含特定语法(${expression})的占位符

tag `string text ${expression} string text` //标签模板字符串
复制代码

2.用法

2.1 在ES6以前能够经过加号实现字符串拼接,但有时建立标签时不能体现出html标签的层级结构,比较繁琐并且容易出错。

let name = 'ghk';
let age = 22;
let output = name + ' is ' + age;
console.log(output);
复制代码

2.2 采用模板字符串简化操做,引入的变量用${}包裹起来,${expression}中的expression的内容能够是一个变量、对象的属性、也能够是一个函数、一个须要建立的标签

let name = 'ghk';
let age = 22;
let output2 = `${name} is ${age}`;
console.log(output2);

let output3 = `${name} is ${age * 3}`;
console.log(output3);
复制代码

2.3 模板字符串书写上能够自由换行,而不用添加“\”反斜杠转义空格

模板字符串建立标签时,有时会保留标签先后的空格,不须要空格时能够用.trim()方法去除空格(模板字符串也是个字符串)。

let str = `<div>
    <p><img src="./images.test.jpg" alt=""></p>
</div>`
let str = `
<div>
    <p><img src="./images.test.jpg" alt=""></p>
</div>.trim()`
console.log(str);
复制代码

2.4 模板字符串里面可嵌套模板字符串

let person = {
    name: 'mss',
    lists:[
        {task: 'reading'},
        {task: 'sleeping'},
        {task: 'eating'}
    ]
};
let template = `
    <ul>
         ${person.lists.map(list =>`
             <li>
                 ${list.task}
             </li>
         `).join('')}
    </ul>
`;
document.body.innerHTML = template;
复制代码

标签模板字符串(Tagged templates)

标签模板字符串容许经过一个默认的函数对其中的插值进行运算和链接。

更高级的形式的模板字符串是带标签的模板字符串。标签使您能够用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其他的参数与表达式相关。最后,你的函数能够返回处理好的的字符串(或者它能够返回彻底不一样的东西)。用于该标签的函数的名称能够被命名为任何名字。

1.用法

1.1 标签函数第一个参数(strings)是一个数组,是由字符串的字面量组成的一个数组;后面的参数是不定参数(即变量),一个参数表明一个表达式的计算结果。

function myTag(strings, ...values) {
   console.log(strings);
   console.log(values);
}
let name = 'ghk';
let task = 'learning English';
let output = myTag`${name} has planned to ${task}`;
复制代码

1.2 固然了,不定参数是能够分开写的,可是若是有多个参数的时候建议仍是使用 ...values 来代替

function myTag(strings,name,task) {
   console.log(strings);
   console.log(name);
   console.log(task);
}
let name = 'ghk';
let task = 'learning English';
let output = myTag`${name} has planned to ${task}`;
复制代码

2.注意点

2.1 当模板字符串是以变量开头或者结尾的时候,返回的数组前或者后会多一个空字符串

若是此时在模板字符串先后加上一些内容,先后就不会返回空字符串了

function myTag(strings,...values) {
   console.log(strings);
   console.log(values);
}
let name = 'ghk';
let task = 'learning English';
let output = myTag`the boy ${name} has planned to ${task}.`;
复制代码

2.2 在上述中使用了标签函数建立的模版字符串,但没有在标签函数中return最终值,因此output是undefined。要想有最终结果须要在标签函数中将字符串字面量数组和表达式运算结果拼接起来返回。

function myTag(strings,...values) {
   //console.log(strings);
   //console.log(values);
   let arr = [];
   for (let i=0;i<strings.length;i++){
       arr.push(strings[i]);
       arr.push(values[i]);
   }
   return arr.join("");
}
let name = 'ghk';
let task = 'learning English';
let output = myTag`the boy ${name} has planned to ${task}.`;
console.log(output); //the boy ghk has planned to learning English.
复制代码

3.原始字符串

3.1 在标签函数的第一个参数中,存在一个特殊的属性raw ,咱们能够经过它来访问模板字符串的原始字符串,而不通过特殊字符的替换。

3.2 使用String.raw() 方法建立原始字符串和使用默认模板函数和字符串链接建立是同样的。

let name = 'ghk';
let task = 'learning English';
let str=String.raw`the boy ${name} has planned to ${task}.`;
console.log(str); //the boy ghk has planned to learning English.
复制代码

解构赋值(Destructuring assignment)

解构赋值语法是一种 Javascript 表达式。经过解构赋值, 能够将属性/值从对象/数组中取出, 赋值给其余变量。

一句话:解构赋值是ES6中新增的一种赋值方式

解构数组(Array destructuring)

1.用法

1.1 解构数组就是在表达式左边定义了要从原变量中取出什么变量。若是想要取出非连续变量的值,须要用加上逗号,表示留出跳过的元素的位置。

let arr= [1,2,3,4,5];
let [a,b] = arr;
// 至关于如下两句
// let a = arr[0];
// let b = arr[1];
console.log(a); //1
console.log(b); //2

let [one,,three,four] = arr;
console.log(one); //1
console.log(three); //3
console.log(four); //4
复制代码

1.2 在数组的解构赋值中, 还可使用ES6中新增的剩余参数来打包剩余的数据;若是使用了剩余参数, 则只能写在最后一个变量的前面。

let [a, ...b] = [1, 3, 5];
console.log("a = " + a); //1
console.log("b = " + b);  //[3,5]

//SyntaxError: Rest element must be last element
let [a, ...b,c] = [1, 3, 5];
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);
复制代码

2.注意点

2.1 在数组的解构赋值中, 等号左边的格式必须和等号右边的格式如出一辙, 才能彻底解构。

let [a, b, [c, d]] = [1, 3, [2, 4]]; //彻底解构
console.log("a = " + a); //1
console.log("b = " + b); //2
console.log("c = " + c); //3
console.log("d = " + d); //4

let [a, b, c] = [1, 3, [2, 4]]; //未彻底解构
console.log("a = " + a); //1
console.log("b = " + b); //3
console.log("c = " + c); //2,4
复制代码

2.2 在数组的解构赋值中, 等号左边的变量个数能够和右边的个数不同,右边的个数也能够和左边的个数不同; 若是右边的个数和左边的个数不同, 能够给左边指定默认值。

let [a, b] = [1, 3, 5];
console.log("a = " + a); //1
console.log("b = " + b); //3

let [a, b, c] = [1];
console.log("a = " + a); //1
console.log("b = " + b); //undefined
console.log("c = " + c); //undefined

let [a, b = 666] = [1, 3, 5];
console.log("a = " + a); //1
console.log("b = " + b); //3
复制代码

3.应用场景

能够用做变量交换,在一个解构表达式中能够交换两个变量的值。 没有解构赋值的状况下,交换两个变量须要一个临时变量

let a = 1;
let b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
复制代码

解构对象(Object destructuring)

数组解构使用[],对象解构使用{},其余用法差异不大。

1.用法(基本赋值)

let obj = {
   name: 'ghk',
   age: 22,
   gender: 'male'
};

let {name, age,gender} = obj;
// 至关于下面几句代码
// let name = obj.name;
// let age = obj.age;
// let gender = obj.gender;
// let {name, age, gender} = {name: 'ghk',age: 22,gender: 'male'};
console.log(name, age, gender);
复制代码

2.无声明赋值

一个变量能够独立于其声明进行解构赋值。

在使用对象字面量无声明解构赋值时,必须在赋值语句周围加上圆括号 ( ) 。

( ) 表达式以前须要有一个分号,不然它可能会被当成上一行中的函数执行。

//正确用法
let a, b;
({a, b} = {a: 1, b: 2});

//错误写法,运行也会报错
let a, b;
{a, b} = {a: 1, b: 2};
console.log(a);
console.log(b);
复制代码

注:{a, b} = {a: 1, b: 2} 不是有效的独立语法,由于左边的 {a, b}被认为是一个块而不是对象字面量。 ({a, b} = {a: 1, b: 2}) 是有效的,至关于var {a, b} = {a: 1, b: 2}

3.注意点

3.1 对象解构只会解构出等号左边出现过的属性名,且左边的变量名称必须和对象的属性名称一致, 才能解构出数据。

let {name} = {name: "ghk",age: 22};
console.log(name); //ghk
let {age} = {name: "ghk",age: 22};
console.log(age); // 34

let {a, b} = {name: 'ghk', age: 22,};
console.log(a, b); // undefined undefined
复制代码

3.2 左边属性名能够多于右边,也能够给左边指定默认值

let {name, age, gender} = {name: "ghk",age: 22};
console.log(name, age, gender); // gender是undefined

let {name, age, gender = 'male'} = {name: "ghk",age: 22};
console.log(name, age, gender);
复制代码

4.对象解构是能够嵌套的

const data = {
    name: 'ghk',
    age: 22,
    skill: {
        language: 'japanese',
        instrument: 'piano',
        hobby: 'hiking',
    }
};
let {language,instrument,hobby} = data.skill;
console.log(language, instrument, hobby);
复制代码

剩余参数(rest parameter)

1.用法

剩余参数 语法容许咱们将一个不定数量的参数表示为一个数组。

一句话:剩余参数是把不少参数整合成一个数组

function sum(...numbers) {
    //number是一个真数组,保存了传进来的全部的变量
    console.log(numbers); 
    //既然返回的是一个数组,那么就可使用数组的各类方法了
    return numbers.reduce((prev,curr) => prev + curr,0)
}
console.log(sum(1, 2, 3, 4)); //10
复制代码

2.使用 剩余参数 和使用 arguments 保存参数的区别?

  • 剩余参数保存参数返回的是一个真数组
  • 利用arguments保存参数返回一个类数组对象
function sum2() {
    console.log(arguments); //arguments返回一个类数组对象
}
sum2(1,2,3,4);
复制代码

3.剩余参数应用场景

3.1 对函数参数的处理(箭头函数中使用),后续能够直接用数组的API处理

3.2 变量的解构,把剩余参数打包到一个数组中

//箭头函数中使用
let sum = (...args) => {
    return args.reduce((prevSum,curValue) => prevSum + curValue);
};
console.log(sum(1, 2, 3));

//把分数解构到score数组中
const player = ['ghk',22,5.4,5.6,7.8,9.9,4.4,6.8];
const [name, age, ...score] = player;
console.log(name);
console.log(age);
console.log(score);
复制代码

扩展运算符(spread operator)

把一个可遍历对象转为一个用逗号分隔的新的参数序列,至关于剩余参数的逆运算

什么是可遍历对象?

就是部署了iterator接口,能够用for of循环的数据类型。包括字符串、数组、arguments对象,DOM、NodeList对象,Generator对象等

1.用法

const arr1 = ['1','1','1','1'];
const arr2 = ['2','2','2'];
//链接数组的做用
let list = [...arr1,...arr2];
console.log(list);// ["1", "1", "1", "1", "2", "2", "2"]


//链接数组并在相应位置插入元素
let list2 = [...arr1,'separate',...arr2];
console.log(list2); // ["1", "1", "1", "1", "separate", "2", "2", "2"]
let list3 = [...arr1,...arr2,'end'];
console.log(list3);// ["1", "1", "1", "1", "2", "2", "2", "end"]
let list4 = ['start',...arr1,...arr2];
console.log(list4);// ["start", "1", "1", "1", "1", "2", "2", "2"]
复制代码

2.rest parameter和spread operator的区别

Just as the spread operator allows you to expand an array into its individual elements, the rest parameter lets you bundle elements back into an array.

推荐看这篇,嘻嘻(龇牙笑) An intro to the spread operator and rest parameter in JavaScript (ES6)

3.扩展运算符能够用来链接数组、克隆数组

下例中newArr复制了arr的元素,修改newArr第一个元素,并不会影响到arr (至关于深拷贝)

let arr1 = ['mary','mark','bob','lily'];
let arr2 = ['tom','eli','jade'];
let arr = [...arr1,...arr2];
console.log(arr); //["mary", "mark", "bob", "lily", "tom", "eli", "jade"]
let newArr = [...arr]; 
console.log(newArr); //["mary", "mark", "bob", "lily", "tom", "eli", "jade"]
newArr[0] = 'rachel';
console.log(newArr); //["rachel", "mark", "bob", "lily", "tom", "eli", "jade"]
console.log(arr); //["mary", "mark", "bob", "lily", "tom", "eli", "jade"]
复制代码

4.扩展运算符能够在函数中使用

let fruits = ['banana','apple','orange'];
let newFruits = ['peach','pear'];
fruits.push(...newFruits);
console.log(fruits);

let time = [2019,10,23];
let date = new Date(...time);
console.log(date);
复制代码

ES6对象字面量加强写法(Object Literal Upgrades)

1.过去定义一个对象的写法

const obj = {
  name: 'ghk',
  age: 18,
  gender: 'male',
  greet: function () 
    console.log(hello);
  }
}
复制代码

2.当一个对象的属性是从外面获取的时候,能够采用下面这种方式

const name = 'ghk';
const age = 18;
const gender = 'man';
  
const obj = {
  name,
  age,
  gender,
  getName(){
    console.log(this.name);
  }
};
复制代码

3.相关阅读

github.com/wesbos/es6-…


本文章参考到的连接: developer.mozilla.org/en-US/docs/…

webfront-js.com/articaldeta…

www.freecodecamp.org/news/spread…

相关文章
相关标签/搜索