ES6的一些新特性

现代浏览器的迅速支持,促使ES6基本成为业界标准。我们今天就来聊一下它的这些新特性:

  • Let与Const声明
  • 模板字符串
  • 对象属性简写
  • for...of和for...in
  • Symbol数据类型
  • 解构赋值
  • Set和Map
  • 箭头函数
  • ES6的扩展
  • Promise
  • Class类
  • 模块化

一、 Let与Const声明

传统var声明的一大局限是变量污染,比如内层变量可能覆盖外层变量,在if或for循环中声明的变量会泄露成全局变量。
为了解决这个问题,ES6引入了let和const命令来进行变量声明。来看下它们的特点和区别:

var——会被视为声明在函数最顶部,有变量提升特性
let——声明局部变量,没有变量提升特性
const——声明常量,声明时必须赋值,且一旦赋值就不能再修改,除非const的是一个对象(对象包含的值可以修改,修改方法见下图)。

const student = { name: 'cc' }
student.name = 'yy';// 不报错
student  = { name: 'yy' };// 报错

二、模板字符串

将表达式嵌入字符串中进行拼接。只要将变量放在${}内即可,整个模板字符串用``包裹起来。

var name = "Lucy", age = 16;
`My name is ${name}, I'm ${age}, I can write like this —— ${name+age}.`

三、对象属性简写

设置对象属性时可以不指定属性名:

const name = 'Ming',
age = '18',
city = 'Shanghai';
const student = {
  name,
  age,
  city
};
console.log(student);

四、for...of和for...in

1、for...of遍历迭代器,如数组:

let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
  console.log(letter);  // 结果: a, b, c
}

2、for...in遍历对象属性:

 let stus = ["Sam", "22", "男"];
 for (let stu in stus) {
   console.log(stus[stu]);  // 结果: Sam, 22, 男
  }

五、Symbol数据类型

用来定义独一无二的值,通过Symbol('字符串')函数来生成。如下图s1和s2,看似一样实则不同:

let s1 = Symbol('web');
let s2 = Symbol('web');
console.log(s1 === s2);
console.log(typeof s1);
console.log(typeof s2);

因为它的值都不相等,所以可以作为对象属性名,有三种方式可以实现——直接赋值、[symbol]、defineProperty(),栗子如下:

// 第一种:直接赋值
let symbol = Symbol();
let a = {};
a[symbol] = 'web';
// 第二种:[symbol]属性
let symbol = Symbol();
let a = {
    [symbol]: 'web'
}
// 第三种:defineProperty
let symbol = Symbol();
let a = {};
Object.defineProperty(a, symbol, {value: 'web'});

获取Symbol属性,可以使用Object.getOwnPropertySymbols()。

六、解构赋值

从数组或对象中提取值,对变量进行赋值。要求等号两边的模式相同。

1、使用方法
  • 获取数组中的值
var foo = ["one", "two", "three", "four"];
var [one, two] = foo;
console.log(one);
console.log(two);
console.log(three);

var [first, , , last] = foo;
console.log(first);
console.log(last);

var a, b; [a, b] = [1, 2];
console.log(a);
console.log(b);
  • 可以方便地交换两个变量的值
var a = 1;
var b = 3; [a, b] = [b, a];
console.log(a);
console.log(b);
  • 获取对象中的值
const student = {
  name: 'Ming',
  age: '18',
  city: 'Shanghai'
};
const {
  name,
  age,
  city
} = student;
console.log(name);
console.log(age);
console.log(city);
2、需要注意的问题:
  • 不能用undefined赋值。
let [x=1] = [undefined];
x;  // 1
  • 注意变量作用域问题
let x;
{x} = {x: 1};  // 这里的大括号外要加小括号

七、Set和Map

Set类似数组,Map类似对象,但它们都没有重复的值,可以进行去重操作。

1. 声明方式

new Set();和 new Map();

let a = new Set([1,2,3,4,5]);
let b = new Map([
    ['name', 'web'],
    ['des', 'js']
])
2. 共有属性

(1)constructor:构造函数
(2)size:元素个数,代替数组的length

3. 操作方法

(1)共有的:delete、has、clear

let a = new Set([1,2,3,4]);
a.delete(2);
console.log(a);  // [1,3,4]
console.log(a.has(3)); // true
a.clear();   // Set(0){}
a.add(6);

(2)Set独有的方法:add()——添加新元素
(3)Map独有的方法
A. set(key, value)——添加新元素
B. get(key)——查找特定数值并返回

3. 共有的遍历方法
  • keys()——返回所有键
  • values()——返回所有值
  • entries()——返回键值对
  • forEach(callbackFn, thisArg)——执行callbackFn操作

八、箭头函数

箭头函数有这样几个特点:

1.不需要function关键字,继承当前上下文的this关键字。
2.只有一个参数时,可以省略();
3.只返回一个表达式时,可以省略{}和return。
4.没有arguments变量
5.不会改变this指向——箭头函数没有自己的this,函数内部的this就是外层代码块的this,举个栗子:

var person = {
    name: "Lucy",
    age: 16,
    func: ()=>{
        console.log(this);
    }
}
person.func(); // window对象

可以发现this是window对象,如果改为普通函数,this指的就是person对象。
那么是不是箭头函数可以完全取代普通函数呢?
并非如此,定义对象时和需要动态this时,不能使用箭头函数。

九、ES6的扩展

ES6在函数、对象、数组对ES5进行了扩展。

1. 函数扩展

(1)默认值:||后 ---> 参数定义后

// es5
function log(x,y) {
    y = y || 'web';
    console.log(x,y);
}
// es6
function log(x,y="web"){
    console.log(x,y);
}

(2)剩余运算符: ...arr表示参数

function web(...arr){
    for(let item of arr){
        console.log(item);
    }
}
web(1,2,3,4,5);

(3)扩展运算符

function add(a,b,c) {
    console.log(a);
    console.log(b);
    console.log(c);
}
var arr = [1,2,3];
add(...arr);
2. 对象的扩展

(1)直接向对象写入变量和函数作为对象的属性和方法
(2)可以使用表达式作为对象的属性
(3)setter和getter
ES6对象的操作方法:
Object.is():比较两个值是否相等。
Object.assign():用于将对象进行合并。Object.getOwnPropertyDescriptor:返回对象属性的描述。
Object.keys()返回一个数组,包含对象自身所有的可枚举属性。

3. 数组的扩展

(1)copyWithin(target,start,end):在当前数组内部,将指定位置的成员复制到其他位置,然后返回当前数组。
(2)target——从该位置开始替换数据。负值表示倒数。
(3)start——从该位置开始读取数据,默认为0。负值表示倒数。
(4)end——到该位置前停止读取数据,默认等于数组长度。负值表示倒数。
(5)find()——找出第一个符合条件的数组成员。
(6)findIndex()——返回第一个符合条件的数组成员的位置,都不符合条件则返回-1。
(7)fill()——填充一个数组,可用于空数组的初始化。
(8)includes()——数组是否包含给定值。

4. 字符串的扩展

(1)s.includes(str)——是否找到了str
(2)s.startsWith(str)——str是否在s的开始位置
(3)s.endsWith(str)——str是否在s的结束位置
它们都支持第2个参数(整型),表示开始匹配的位置

十、Promise

Promise对象表示异步操作的最终状态。它是异步编程的一种解决方案,可以将异步操作用同步操作的流程表达出来,避免层层嵌套,并且提供统一的接口,更方便控制异步操作。
Promise构造函数接收一个函数作为参数,这个函数又有两个参数分别是resolve和reject,如下:

const promiseObj = new Promise(function(resolve,reject){
    // code
    if(/*异步操作成功*/){
        resolve(value);
    }else{
        reject(error);
    }
})

Promise实例生成后,可以用then方法分别指定resolved状态和rejected状态的回调函数。这两个回调函数都接收Promise对象传出的值作为参数,其中第一个回调函数在Promise对象状态变为resolved时调用,第二个在rejected状态时调用(第二个回调函数可选),来段代码:

promiseObj.then(function(value){},function(error){})

十一、Class类

ES6引入Class类,让js的面向对象编程更简单和易于理解。可以使用class构造对象,二是可以使用extends实现继承。

class Point{
    constructor(x,y){
        this.x = x;  // 初始化
        this.y = y;
    }
    toString(){
        return `(${this.x},${this.y})`;
    }
}
let p = new Point(10,20);
console.log(p.x, p.y);
console.log(p.toString());

// 继承
class ColorPoint extends Point{
    constructor(x,y,color){
        super(x,y);
        this.color = color;
    }
    showColor(){
        console.log('这个点的颜色是'+this.color);
    }
}
let cp = new ColorPoint(30,40,'red');
console.log(cp.x, cp.y);
console.log(cp.toString());
cp.showColor();

十二、模块化

模块的功能主要由 export 和 import 组成。每个模块都有自己单独的作用域,通过 export 来规定对外暴露的接口,通过import引用其它模块提供的接口。

1、export导出

可以使用export导出多个变量或函数

  • 导出变量/常量
export var name = 'Rainbow';  // 导出变量
export const sqrt = Math.sqrt;  // 导出常量
  • 导出多个变量
var name = "Rainbow";
var age = 24;
export {
  name,
  age
}
  • 导出函数
export function supModule(args){
  return args;
}
2、import导入

定义好模块的输出以后就可以在另一个模块引用了。

  • 一条import 语句可以同时导入默认函数和其它变量
import testMethod, {otherMethod} from 'xxx.js';
  • 可以为变量起别名
import { otherMethod as om } from 'xxx.js'

十三、其他高级用法

1. Iterator遍历器

它可以为各种数据结构提供统一接口。

2. Genera函数

也是一种异步编程解决方案,返回一个遍历器对象,可以依次遍历Generator函数的每个状态。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342