01 简介
一、检测es6兼容性
http://kangax.github.io/es5-compat-table/es6
二、兼容包:traceur转码器
<script src="http://google.github.io/traceur-compiler/bin/traceur.js" type="text/script"></script>
<script>
traceur.options.experimental = true; // experimental /ɛk'spɛrɪ'mɛntəl/:实验的,试验性的
</script>
<script type="module"> // type得是module或者traceur,不是text/javascript
class Test = function() {}
</script>
三、es7
async函数:在promise和generator的基础上,提出的异步操作解决方案。
02 let基本用法
一、let不存在变量提升
二、let暂时性死区
只要块级作用域内存在let命令,它所声明的变量就”绑定“到这个区域,不再受外部的影响。
三、let不允许在相同作用域内,重复声明一个变量。
06 为什么需要块级作用域
一、为什么需要块级作用域
1、防止变量相互影响。
2、变量作用域内使用完后即销毁,减少内存占用。
var time = new Date();
function func() {
console.log(time);
if (false) {
var time = "hello world"; // 声明的变量会提升,但是赋值没有提升
}
}
func(); // 控制台输出”undefined“
08 const命令
一、const用来声明常量,声明的是常量。
常量:一旦声明,常量的值就不能改变。
对于引用类型,只要指向的内存地址没变,就是常量。
二、const对象
const person = {};
person.name = ‘zhangsan’; // 指向的内存地址没变
person = {}; // 报错:Uncaught TypeError: Assignment to constant variable.
const arr = [];
arr.push('hello');
arr.length = 0;
console.log(arr);
arr = ['hello world']; // 报错:Uncaught TypeError: Assignment to constant variable.
10 const对象冻结
一、使用const冻结对象
const person = Object.freeze({
name: 'zhangsan',
age: '30'
});
console.log(person.name); // 'zhangsan'
person.name = 'lisi';
console.log(person.name); // 'zhangsan'
二、彻底冻结对象(递归)
var constantize = obj => {
Object.freeze(obj);
Object.keys(obj).forEach((key, value) => {
if (typeof obj[key] === 'object') {
constantize(obj[key]);
}
})
}
11 跨模块常量
一、面向对象,模块至少是一个类。
12 全局对象属性
一、全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js指的是global对象。在javsScript语言中,所有全局变量都是全局对象的属性(node的情况比较特殊,这条只对REPL捐精适用,模块环境必须显示声明成global的属性)。
二、es6规定,var命令和function命令声明的全局变量,属于全局对象的属性:let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。
var a = 1;
console.log(window.a); // 1
let b = 2;
console.log(window.b); // undefined
13 Destructuring 数组的解构赋值
一、结构destructuring
es6允许按照一点模式,从数组和对象中提取值,对变量进行赋值,这被称为解构。
var [a, b, c] = [1, 2, 3];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
let [foo, [[bar], base]] = [1, [[2], 3]];
二、不完全解构
等号左边的模式,只匹配一部分的等号右边的数组。
let [a, [b], c] = [1, [2, 3], 4];
console.log(a); // 1
console.log(b); // 2
console.log(c); // 4
三、指定默认值
es6内部使用严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。
// 1
var [temp = 'string'] = [];
console.log(temp); // string
// 2:string为默认值,如果后面的数组没有值(为undefined,不为null),则temp为默认值string,如果有值,则为后面的值tempString。
var [temp = 'string'] = ['tempString'];
console.log(temp); // tempString
// 1
var a = 1;
a = undefined;
console.log(a); // undefined
// 2
var [x, y = "aaa"] = ["bbb", undefined];
console.log(x); // bbb
console.log(y); // aaa
var [temp] = 1; // 不管是1,还是false、NaN、undefined、null都会报错(都是不可Iterable,不可迭代)。
四、let和const命令
只要某种数据结构具有iterator接口,都可以采用数组形式的解构赋值。
iterator/ɪtə’retɚ/:迭代器,迭代程序。
// 1
let [a, b, c] = new Set(['a', 'b', 'c']);
console.log(a); // a
// 2
const [x, y, z, a, b, c] = new Set([3, 1, 2, 2, 3]); // new Set()处理后的数组:[3, 1, 2]
console.log(x); // 3
console.log(y); // 1
console.log(z); // 2
console.log(a); // undefined
console.log(b); // undefined
console.log(c); // undefined
function* fibs() { // function*表示生成器函数,生成器函数在执行时能暂停,后面又能从暂停处继续执行
let a = 0;
let b = 1;
while (true) {
console.log(`a:${a}`); // 0 1 1 2 3 5
console.log(`b:${b}`); // 1 1 2 3 5 8
yield a;
[a, b] = [b, a+b];
}
}
let [first, second, third, fourth, fifth, sixth] = fibs();
console.log(first); // 0
console.log(second); // 1
console.log(third); // 1
console.log(fourth); // 2
console.log(fifth); // 3
console.log(sixth); // 5
1、yield是ES6的新关键字,使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。
2、yield关键字实际返回一个IteratorResult(迭代器)对象,它有两个属性,value和done,分别代表本次yeild表达式的返回值和是否完成(生成器后续是否还有yield语句)。
3、调用 next() 方法时,如果传入了参数,那么这个参数会作为上一条执行的 yield 语句的返回值。
4、当在生成器函数中显式 return 时,会导致生成器立即变为完成状态,即调用 next() 方法返回的对象的 done 为 true。如果 return 后面跟了一个值,那么这个值会作为当前调用 next() 方法返回的 value 值。
五、数组有length属性,可以对这个属性解构赋值
const {length: len}= ['hello','world'];
console.log(len); // 2
17 对象的解构赋值
一、解构
对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
var {name, age} = {age: 28, name: 'Jack'};
console.log(age); // 28
// 1
var {userName: person_name, age: person_age} = {userName: 'Jack', age: 28}; // name的值赋给person_name
console.log(person_age); // 28
console.log(userName); // userName is not defined
// aSuncat:如果userName写成name,打印name并不会报错。因为name是全局对象window的属性,window.name是窗口的名字,窗口的名字主要用于为超链接和表单设置目标(targets)
// 2
let object = {first: 'Hello', last: 'World'};
let {first: firstName, last: lastName} = object;
console.log(firstName); // Hello
二、默认值生效的条件是,对象的属性值严格等于undefined
let {message: msg = "you are a person"} = {};
consolel.log(msg); // you are a person
let {x = 1} = {x: undefined};
console.log(x); // 1
let {y = 2} = {y: null};
console.log(y); // null
三、已声明变量的解构赋值
var x;
({x} = {x: 1}); // 如果没有(),会报错:Uncaught SyntaxError: Unexpected token =,javascript引擎会将{x}理解成一个代码块,这个代码块是没有声明的。
console.log(x); // 1
四、现有对象的方法
对象的解构赋值,可以很方便地将现有对象的方法,赋值到某个变量。
console.log(Math.sin(Math.PI/6)); // 0.49999...
浮动数运算机制
let {sin, cos, tan} = Math;
console.log(sin(Math.PI/6));
20 字符串的解构赋值
一、字符串被转换成了一个类似数组的对象。
const [a, b, c, d, e] = 'hello';
console.log(a); // h
console.log(b); // e
二、属性解构赋值
类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。
const {length: len} = 'hello';
console.log(len);
21 函数参数的解构赋值
一、函数的参数也可以使用解构
function sum([x, y]) {return x + y;}
console.log(sum[1, 2]); // 3
二、函数的参数也能使用默认值
function fun({x = 0, y = 0} = {}) {
return [x, y];
}
console.log(fun({x: 100, y: 200})); // [100, 200]
console.log(fun({x: 100})); // [100, 0]
console.log(fun({})); // [0, 0]
console.log(fun()); // [0, 0]
function fun({x, y} = {x: 0, y:0}) {return [x, y]};
console.log(fun({x: 100})); // [100, undefined]
console.log(fun({})); // [undefined, undefined]
console.log(fun()); // [0, 0] // 没有在函数参数中解构赋值,只是对对象解构赋值,{x,y} = {x: 0, y: 0}会被当成是在函数中执行的语句
22 交换变量的值
一、解构赋值的用途
1、交换变量的值
// es5
var a = 100;
var b = 200;
var temp = a; // 多声明一个变量,就多占用一份内存空间
a = b;
b = temp;
// es6
let x = 100;
let y = 200;
[x, y] = [y, x]; // 交换x,y的值
2、从函数返回多个值
// 数组
function fun() {
return [1, 2, 3];
}
var [x, y, z] = fun();
console.log(x); // 1
console.log(y); // 2
// 对象
function fun() {
return {
id: '007',
name: 'canan',
age: 28
}
var {id, name, age} = fun();
console.log(id);
}
3、函数参数的定义
// 参数是一组有次序的值
function([x, y]) {
// x = 100
// y = 200
};
fun([100, 200]);
// 参数是一组无次序的值
function fun({id, userName, age}) {
// id = '007'
// userName = 'conan'
// age = 28
}
fun({id: '007', userName: 'conan', age: 28});
4、提取json数据
var jsonData = {
id: "007",
userName: "conan",
age: 28,
score: {Chinese: 98, English: 107}
}
console.log(jsonData);
let {id: number, userName, age, Chinese: Chinese} = jsonData
console.log(number);
console.log(userName);
console.log(score.Chinese)
5、函数参数的默认值
// 对象的解构赋值传值,好处:避免了在函数体内部再写var foo = config.foo || 'default foo' 这样的语句
jQuery.ajax = function(url, {
async = true,
beforeSend = function() {},
cache = true,
complete = function() {},
crossDomain = false,
global = true,
// ...more config
}) {
// ... do stuff
}
6、遍历map结构
var map = new Map();
map.set('id', '007');
map.set('age', 28);
console.log(map); // Map(2) {"id" => "007", "age" => 28}
console.log(typeof map); // object
for (let [key, value] of map) {
console.log(`${key}is${value}`);
}
// 获取键名
for(let [key] of map) {
console.log(key); // id, age
}
// 获取值
for (let [, value] of map) {
console.log(value); // 007, 28
}
7、输入模块的指定方法
(1)require.js 智能模块
// 先引入require.js
// requirejs的应用
const {SourceMapConsumer, SourceNode} = require('source-map');
另外一个视频中的es6
1、
// tagged-template
let dessert = 'a';
let drink = 'b';
let breakfast = kitchen `今天的早餐是 ${dessert} 与 ${drink} !`
function kitchen(strings, ...values) {
console.log(strings); // 今天的早餐是 与 !
console.log(values); // a b
}
// string-function
console.log(
breakfast.startWith('今天'); // 以什么字符串开头
breakfast.endWith('!'); // 以什么字符串结尾
breakfast.includes('今天'); // 包含什么字符串
)
2、function name :得到函数名
let breakfast = function latestBreakfast() {}
console.log(breakfast.name); // latestBreakfase
3、object-literal
let dessert = ‘a';
let obj = {
dessert,
drink = 'b',
breakfast() {} // 等价于breakfast: function() {}
}
4、
console.log(+0 == -0); // true
console.log(+0 == -0); // true
console.log(NaN == NaN); // false
Object.is (+0, -0); // false
Object.is (NaN, NaN); // true
5、Object.setPrototypeOf可以在创建对象之后改变对象的prototype
Object.getPrototypeOf可以设置对象的prototype
let breakfast = {
getDrink() {return 'a';}
}
let dinner = {
getDrink() {return 'b';}
}
let sunday = Object.create(breakfast);
console.lob(Object.getPrototypeOf(sunday) === breakfast); // true
Object.setPrototypeOf(sunday, dinner);
console.log(Object.getPrototypeOf(sunday) === breakfast); // false
6、es6的__proto__可以设置对象的prototype
let sunday = {
__proto__: breakfast
}
console.log(Object.getPrototypeOf(sunday) === breakfast); // true
7、
let sunday = {
__proto__: breakfast,
getDrink() {
return super.getDrink() + '1'; // super.getDrink()就是breakfast.getDrink()
}
}
console.log(sunday.getDrink()); // a1
8、Iterators:迭代器
(1)特点:①每次执行的时候会返回一个对象,一个是value, 一个是done。
②迭代器里有next方法,执行这个方法会返回一个对象,对象有value, done属性。如果没有迭代的里,value就是undefined, done就是true了
(2)手写一个迭代器
function chef(foods) {
let i = 0;
return {
next() {
let done = (i >= foods.length);
let value = !done ? foods[i++] : undefined;
return {
value,
done
}
}
}
}
let wanghao = chef([1, 2]);
console.log(wanghao.next()); // {value: 1, done: false}
console.log(wanghao.next()); // {value: 2, done: false}
console.log(wanghao.next()); // {value: undefined, done: true}
9、genarators
手工创建迭代器比较麻烦,可以用generator创建生成器
function* chef() {
yield 'a';
yield 'b';
}
let wanghao = chef(); // 利用生成器创建迭代器
console.log(wanghao.next()); // {value: 'a', done: false};
let chef = function* (foods) {
for(var i = 0; i < foods.length; i++) {
yield foods[i];
}
}
let wanghao = chef(['a', 'b']);
10、class类里有get, set方法
11、静态化类:不需要实例化类就能使用的方法。可以用static关键词
class Chef {
static cook(food) { // 使用了static // 如果cook前面没有static,执行Chef.cook('a')则会报错:Chef.cook is not a function
console.log(food);
}
}
Chef.cook('a'); // 不用new Chef
12、Set:add size has delete forEach clear
let desserts = new Set('123');
desserts.add('4');
desserts.add('4');
console.log(desserts); // Set(4){'1', '2', '3', '4'}
console.log(desserts.size); // 4
console.log(desserts.has('1')); // true
desserts.delete('2');
console.log(desserts); // Set(3){'1', '3', '4'}
desserts.forEach(dessert => {
console.log(dessert);
})
desserts.clear();
console.log(desserts); // Set(0){}
13、Map:set size get delete has forEach clear
let food = new Map();
console.log(food);
let fruit = {}, cook = function() {}, dessert = '糕点';
food.set(fruit, 'a'); // 往map里添加名字
food.set(cook, 'b');
food.set(dessert, 'c');
console.log(food.size); // 3
console.log(food.get(fruit)); // a
food.delete(dessert);
console.log(food.has(dessert)); // false
food.forEach((value, key) => {
console.log(`${key} = ${value}`);
})
food.clear();
console.log(food); // Map(0) {}
14、module:es6需要借助webpack或jspm
<script src="node_module/babel-core/browser.js"></script>
<script src="node_mobule/babel-core/browser-polyfill.js"></script>
<script src="jspm_package/system.js"></script>
<script src="config.js"></script>
<script>
System.import('script');
</script>
<script src="script.js" type="text/babel"></script>
(1)可以到处的有:变量,函数,类等等。
(2)导出默认的东西不需要大括号{},
import {food, chef} from '';
import food from ''; // food是默认导出的东西
export {dinner as default}; // 将dinner这个模块作为默认要导出的东西
---------------------
作者:aSuncat
来源:优快云
原文:https://blog.youkuaiyun.com/aSuncat/article/details/88568483
版权声明:本文为博主原创文章,转载请附上博文链接!