es6特性

1 let const

1.1 let

let 声明的变量是在其块级作用域起作用,与 var 相似。二者之间最主要的区别在于 var 声明的变量的作用域是整个封闭函数。

示例1:let 对比 var

var a = 5;
var b = 10;

if (a === 5) {
  let a = 4; // a 作用域是 if 代码块内;
  var b = 1; // b 作用域是 整个函数;

  console.log(a);  // 4
  console.log(b);  // 1
} 

console.log(a); // 5
console.log(b); // 1

let的作用域是块,而var的作用域是函数

示例2:let 在循环中

for (let i = 0; i < 10; i++) {
  console.log(i); // 0, 1, 2, 3, 4 ... 9
}

console.log(i); // i is not defined

可以用 let 来代替 var ,在 for 定义块中使用块级变量.

1.2 const

const 是用来声明常用的,常量的值不能通过重新赋值来改变,并且不能重新声明。

const number = 42;

try {
  number = 99;
} catch(err) {
  console.log(err); // TypeError: Assignment to constant variable.
}

console.log(number); // 42

2 字符串模板

以前的写法:

$("#content").append(
  "我是" + obj.name + "</b> " +
  "的爸爸, " +
  "今年" + obj.age + "岁!"
);

我们要用一堆的'+'号来连接文本与变量,而使用ES6的新特性模板字符串``(顿号)后,我们可以直接这么来写:

$("#content").append(`
  我是${obj.name} 
  的爸爸, 
  今年${obj.age}岁!
`);

使用用${}来引用变量,而且所有的空格和缩进都会被保留输出。

3 箭头函数

3.1 箭头函数与普通函数对比:

function show(a) { return a } ;
对应箭头函数写法:
let show = a => a;  


function show(a,b) { return a+b } ;
对应箭头函数写法:
let show = (a, b) => a+b;  


function show() { return 'welcome' } ;
对应箭头函数写法:
let show = () => 'welcome';  


function show() { alert(1); return 'hi' } ;
对应箭头函数写法:
let show = () => { alert(1); return 'hi' }; 

3.2 this 说明

// 没有独立作用域
let obj = {
  commonFn: function () {
    console.log(this); // 普通函数,this指向调用函数。
  },
  arrowFn: () => {
    console.log(this); // 箭头函数,没有独立作用域,与 obj 所在的作用域相同。
  }
}

obj.commonFn(); // this 指向 obj 作用域;
obj.arrowFn(); // this 指向 obj 所在作用域,window。

结果

4 Promise

  • 就是一个对象,用来传递和处理异步操作的数据
  • 状态:
 pending(等待)  →  Resolve(成功)
                 →  Reject(失败)

promise 的状态只能从 pending 到 resolve,或者从 pending 到reject。

4.1 Promise常见结构

new Promise((resolve, reject) => {
  $.ajax({
    url: 'xxx',
    type: 'post',
    success: (result) => {
      resolve(result);
    },
    error: (err) => {
      reject(err);
    }
  });
}).then((result) => {
  console.log("成功", result);
}, (err) => {
  console.log("失败", err);
});

4.2 promise链式调用

let promiseFn1 = new Promise((resolve, reject) => {
  $.ajax({
    url: 'xxx',
    type: 'post',
    success: (result) => {
      resolve(result);
    },
    error: (err) => {
      reject(err);
    }
  });
});

let promiseFn2 = new Promise((resolve, reject) => {
  $.ajax({
    url: 'xxx',
    type: 'post',
    success: (result) => {
      resolve(result);
    },
    error: (err) => {
      reject(err);
    }
  });
});

promiseFn1.then((result) => {
  console.log("promiseFn1 成功被调用", result);
  return promiseFn2; // 这里返回的是第二个 promiseFn2 !!!
}).then((result) => {
  console.log("promiseFn2 成功被调用");
});


4.3 promise使用

4.3.1 then

then基础用法:

var p1 = new Promise(function (resolve, reject) {
  resolve('1');
  // reject('2');
});
p1.then(function (val) {
  alert('resolve,成功调用函数' + val);
}, function (val) {
  alert('reject,失败调用函数' + val);
});


then 链式调用:

var p1 = new Promise(function (resolve, reject) {
  resolve(1);
});
p1.then(function (val) {
  console.log(val); // 1
  return val + 1; // 这里返回的值,给下一次then调用
}, function (val) {
  alert('reject,失败调用函数' + val);
}).then(function (value) { // then链式调用
  console.log(value); // 2
})

then ajax的应用:重要的是思想

function ajax(url, fnSucc, fnFail) {
  let oAjax = new XMLHttpRequest();
  oAjax.open('GET', url, true);
  oAjax.send();
  oAjax.onload = function () {
    if (oAjax.readyState == 4 && oAjax.status == 200) {
      fnSucc(oAjax.responseText);
    } else {
      fnFail(oAjax.status);
    }
  }
}

let p1 = new Promise(function (resolve, reject) {
  ajax("url", function (result) { // 进行ajax的调用
    resolve(result);
  }, function (result) {
    reject(result);
  })
});
p1.then(function (val) {
  console.log('成功' + val);
}, function (val) {
  console.log('失败' + val);
});


4.3.2 catch(用来捕获错误)

var p1 = new Promise(function (resolve, reject) {
  resolve('成功了');
});
p1.then(function (val) {
  console.log(val); // 成功了
  throw '发生错误了';
}).catch(function (e) {
  console.log(e); // 发生错误了
});


4.3.3 all

用于将多个promise对象,组合、包装成一个全新的promise对象。
Promise.all([p1, p2, p3...]);所有的promise成功了,才能算是成功,否则,只要有一个失败了,就是失败。

var p1 = Promise.resolve(1); // resolve 成功
var p2 = Promise.reject(2); // reject 失败

Promise.all([true, p1]).then(function (val) {
  console.log(val); // 输出: 数组 [true, 1]
}, function (val) {
  console.log("失败了" + val);
});

Promise.all([true, p1, p2]).then(function (val) {
  console.log("成功了" + val);
}, function (val) {
  console.log("失败了" + val); // 输出: 失败了2
});


4.3.4 race

哪个promise先返回,就使用哪个

var p1 = new Promise(function (resolve, reject) {
  setTimeout(() => {
    resolve('one');
  }, 500);
});
var p2 = new Promise(function (resolve, reject) {
  setTimeout(() => {
    resolve('two');
  }, 100);
});

Promise.race([p1, p2]).then(function (val) {
  console.log("成功了" + val); // 成功了two
});


4.3.5 reject

Promise.reject() -- 生成一个错误的promise

4.3.6 resolve

Promise.resolve() -- 生成一个成功的promise

5 对象

5.1 对象字面量的定义写法

5.1.1 es5 定义对象字面量的写法:

var name = "xiaoming",
  age = 1;
var obj = {
  name: name,
  age: 2,
  getName: function () {
    return this.name;
  },
  getAge: function () {
    return this.age;
  }
}

console.log(obj.getName()); // 小明
console.log(obj.getAge()); // 2


5.1.2 es6 定义对象字面量的写法

let name = "xiaoming",
  age = 1;
let obj = {
  name, // 变量名可以直接使用对象的属性名称
  age: 2,
  getName() { // 对象里的方法可以简写
    return this.name;
  },
  getAge() {
    return this.age;
  }
}

console.log(obj.getName()); // xiaoming
console.log(obj.getAge()); // 2


5.2 单例模式:json key--value 简写

var name = 'abc';
var age = 11;
var person = {
  name,
  age,
  showName: () => {
    alert(this.name); // 输出:abc
  },
  showAge: () => {
    alert(this.age);
  }
}
person.showName(); // 箭头函数 this 指向跟 person 同级的作用域, window


5.3 面向对象

5.3.1原型继承写法

// 又是类,又是构造函数
function Person(name, age) {  
  this.name = name;
  this.age = age;
}
Person.prototype.showName = function () {
  return this.name;
}
Person.prototype.showAge = function () {
  return this.age;
}

// (原型)继承  子类.prototype = new 父类()
function Worker(name, age) {
  Person.apply(this, arguments);
}
Worker.prototype = new Person(); // 子类.prototype = new 父类()

var p = new Person('abc', 11);
alert(p.showAge()); // 11

var w = new Worker('abcd', 191);
alert(w.showAge()); // 191


(原型)继承 子类.prototype = new 父类();

5.3.2 类和构造函数

class Person { // 类
  constructor(name, age) { //构造函数
    this.name = name;
    this.age = age;
  }
  showName() {
    return this.name;
  }
  showAge() {
    return this.age;
  }
}
var p = new Person('abc', 121);
alert(p.showAge()); //121


5.3.3 继承

// 父类
class Person { // 类
  constructor(name, age) { //构造函数
    this.name = name;
    this.age = age;
  }
  showName() {
    return this.name;
  }
  showAge() {
    return this.age;
  }
}
var p = new Person('abc', 121);
alert(p.showAge()); //121

// 继承,子类继承父类
class Worker extends Person {
  constructor(name, age, job = '卖报') { // 默认值
    super(name, age); // 调用父类的构造函数
    this.job = job;
  }
  showJob() {
    return this.job;
  }
}
var w = new Worker('abc', 11);
alert(w.showAge()); // 11
alert(w.showJob()); // 卖报



5.3.4 对象应用举例

// 模拟队列
class Queue {
  constructor(content = []) {
    this._queue = [...content];
  }
  shift() {
    var val = this._queue[0];
    this._queue.shift(); // 这个才是重要的,模仿删除第一个元素
    return val; // 返回删除的元素值
  }
  push(n) {
    this._queue.push(n); // 这个才是重要的
    return this._queue.length; // 返回新增后数组长度
  }
}
let q = new Queue([1, 2, 3, 4]);
q.shift();
q.push(5);
console.log(q._queue);


6 ES6模块化

以前:seajs、requirejs

6.1 如何定义导出、导入模块

6.1.1 导出模块

// aa.js
const a = 11;
export default a


6.1.2 导入模块

// bb.js:
import modA from './aa.js'
alert(modA) // 11

导入和导出模块使用 export 和 import 关键字。

6.2 导出导入函数

// aa.js
const a = 12;
export default a;


// bb.js
const b = 2;
export default b;


// s_sum.js
import modA from './aa.js';
import modB from './bb.js';

export default function s_sum() {
  return modA + modB;
};


// index.js
import sumMod from './s_sum';
alert(sumMod()); // 导出来的模块是函数


6.3 导出、导入多个模块

6.3.1 导出多个模块

// aa.js:使用对象导出多个模块
const a = 12;
const b = 13;
export default {a, b}

6.3.2 导入多个模块

// bb.js:引用
import c from './aa.js';
var a = c.a;
var b = c.b;

6.4 默认导出、导入模块

6.4.1 对比使用命名导出

6.4.1.1 使用命名导出
// module "my-module.js"
function cube(x) {
  return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
var graph = {
    options: {
        color:'white',
        thickness:'2px'
    },
    draw: function() {
        console.log('From graph draw function');
    }
}
export { cube, foo, graph };


6.4.1.2 使用命名导入
import { cube, foo, graph } from 'my-module';
graph.options = {
  color: 'blue',
  thickness: '3px'
};
graph.draw();
console.log(cube(3)); // 27
console.log(foo);    // 4.555806215962888


6.4.2 默认导出、导入

6.4.2.1 默认导出
// module "my-module.js"
export default function cube(x) {
  return x * x * x;
}

6.4.2.2 默认导入
// module "my-module.js"
import cube from 'my-module';
console.log(cube(3)); // 27​​​​​

说明:

import a, {b, c} from mode;

  • 不用大括号包起来的导入模块 a,表示是 mode 中用 export default a 导出的默认模块;
  • b、c 是 export 导出的模块,不是默认mode中的默认模块。

7 常见知识点

7.1 超链接(三个点...)应用

function show(...args) {
  args.push(4);
  console.log(args);
}
show(1, 2, 3);


7.2 解构和释构

const data = [...this.state.gData];
等同于:
const { gData } = this.state;
const data = [...gData];

如果你理解上面代码的意思,那解构和释构基本就算过关了。

7.3 循环嵌套

let values = [1, 2, 3];
let str = `<ul>${values.map(value => `<li>值为:${value}</li>`).join('')}</ul>`

console.log(str);

结果

7.4 复制数组

7.4.1 for循环

let arr = [1, 2, 3];
let arr2 = [];
for (let i = 0; i < arr.length; i++) {
  arr2[i] = arr[i]
}

console.log(arr, arr2);
arr2.pop();
console.log(arr, arr2);
console.log(arr === arr2);

结果

7.4.2 Array.from(arr)

let arr = [1, 2, 3];
let arr2 = Array.from(arr);

console.log(arr, arr2);
arr2.pop();
console.log(arr, arr2);
console.log(arr === arr2);

结果

7.4.3 超链接(三个点...)

let arr = [1, 2, 3];
let arr2 = [...arr];

console.log(arr, arr2);
arr2.pop();
console.log(arr, arr2);
console.log(arr === arr2);

结果

7.5 循环

7.5.1 普通 for

let arr = ['apple', 'bannel', 'cat'];
for (let i in arr) {
  console.log(i); // 0, 1, 2 索引
}

7.5.2 for in

// 数组:
let arr = ['apple', 'bannel', 'cat'];
for (let i in arr) {
  console.log(i); // 0, 1, 2 索引
}

// json
var json = { 'a': 'apple', 'b': 'bannel', 'c': 'cat' };
for (let i in json) {
  console.log(i); // a, b, c 索引
}

7.5.3 for of

let arr = ['apple', 'bannel', 'cat'];
for (let i of arr) {
  console.log(i); // 'apple', 'bannel', 'cat' 值
}

for of 可以循环数组,但是不能循环 json 对象,其真正的用途是用于循环 map 对象。

7.6 Map 对象

和 json 相似,也是一种key-value形式,Map对象为了和for of 循环配合而生的。

7.6.1 Map对象创建、设置、获取和删除操作

// 创建Map对象
var map = new Map();

// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');

// 获取值
map.get('a');

// 删除
map.delete('a');
console.log(map);

结果

7.6.2 map 配合 for of

7.6.2.1 方式一

Map 对象

// map 配合 for of
var map = new Map();
// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');
for (let name of map) {
  console.log(name);
}

结果
7.6.2.2 方式二

Map 对象

var map = new Map();
// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');
for (let name of map.entries()) {
  console.log(name);
}

结果
7.6.2.3 方式三

key - value

var map = new Map();
// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');

for (let [key, val] of map) {
  console.log(key, val);
}

结果
7.6.2.4 方式四

获取 key

var map = new Map();
// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');

for (let k of map.keys()) { // a,b,c -- key
  console.log(k);
}

7.6.2.5 方式五

获取 value

var map = new Map();
// 设置值
map.set('a', 'apple');
map.set('b', 'bannel');
map.set('c', 'cat');

for (let val of map.values()) { // value
  console.log(val);
}

结果

8 简单总结

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

推荐阅读更多精彩内容

  • ES6特性归纳 ES的全称是ECMAScript,它是JavaScript的规格,JS是ES的一种实现。ES还有J...
    FWHeart阅读 560评论 0 4
  • JavaScript社区中的每个人都喜欢新API、新语法和新特性——可以更优雅,更智能,更有效的完成重要任务。ES...
    安石0阅读 117评论 0 0
  • es6相较之前es5,增加了许多新的特性,提高了javascript体验,我在es6学习和使用的过程中进行了纪录。...
    YomonAh阅读 227评论 0 2
  • 不知道你现在是否也和我一样翻阅着手机,却不知道从何读起,我们很无聊,每天重复同样一件事情,睁眼,起床,工作,抱怨几...
    复制粘贴再删除阅读 489评论 0 0
  • 2017-02-25 四猫先生 蔡老师,我家孩子每天起床我都得叫上好几遍,平时衣来伸手,饭来张口,真是愁死我了。 ...
    四猫先生阅读 312评论 1 2