【笔记-es6】《麦子学院-ECMAScript6编程艺术》、《es6》

20190315:《麦子学院-ECMAScript6编程艺术》

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);  // aaa
console.log(y); // bbb
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');

20190316:《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这个模块作为默认要导出的东西

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值