ES6入門基礎(chǔ)
推薦書籍 《ECMAScript 6 入門》:http://es6.ruanyifeng.com/
碼云倉庫代碼(歡迎Start)
碼云倉庫代碼-https://gitee.com/hongjunyong/es6-imooc-lottery
1、為什么要學(xué)習(xí)ES6

detail.png
1.1、對(duì)象拷貝

copy.png
1.2、參數(shù)傳遞

data.png
1.3、更多特性:解構(gòu)賦值、箭頭函數(shù)、set和map、異步操作、類與對(duì)象、模塊化
2、項(xiàng)目構(gòu)建(略)
// -e要使用ejs模版引擎 .當(dāng)前目錄執(zhí)行
express -e .

express.png
// 安裝依賴:npm install
npm install gulp gulp-if gulp-concat webpack webpack-stream vinyl-named gulp-livereload gulp-plumber gulp-rename gulp-uglify gulp-util y
args --save-dev
項(xiàng)目運(yùn)行 gulp --watch
3、ES6語法
3.1、let const命令(案例:lesson1-let-const.js)
3.1.1、let的生命周期
// i在for循環(huán)外面依舊有效
for(var i=1;i<3;i++){
console.log(i);
}
console.log(i);
// i只有在for循環(huán)里面有效,出了括號(hào)生命周期結(jié)束
for(let i=1;i<3;i++){
console.log(i);
}
console.log(i);

let.png
3.1.2、let變量不能重復(fù)定義
錯(cuò)誤:
let a = 1;
let a = 2;
3.1.3、const常量不能修改,對(duì)象可以修改(指針),且聲明的時(shí)候必須賦值
const常量不能修改
錯(cuò)誤:
const a = 1;
a = 2;
對(duì)象可以修改
正確:
const k = {
a:1
}
k.b = 3;
聲明的時(shí)候必須賦值
錯(cuò)誤:
const a;
a = 1;
正確:
const a = 1;
3.1.4、es6開啟嚴(yán)格模式('use strict')
3.1.4.1 不允許使用未聲明的變量
"use strict";
x = 3.14; // 報(bào)錯(cuò) (x 未定義)
3.1.4.2 不允許使用未聲明的變量(對(duì)象也是一個(gè)變量)
"use strict";
x = { p1: 10, p2: 20 }; // 報(bào)錯(cuò) (x 未定義)
3.1.4.3 不允許刪除變量或?qū)ο?/h5>
"use strict";
var x = 3.14;
delete x; // 報(bào)錯(cuò)
3.1.4.4 不允許刪除函數(shù)
"use strict";
function x(p1, p2) {};
delete x; // 報(bào)錯(cuò)
3.1.4.5 不允許變量重名
"use strict";
function x(p1, p1) {}; // 報(bào)錯(cuò)
3.1.4.6 不允許使用八進(jìn)制
"use strict";
var x = 010; // 報(bào)錯(cuò)
3.1.4.7 不允許使用轉(zhuǎn)義字符
"use strict";
var x = \010; // 報(bào)錯(cuò)
3.1.4.8 不允許對(duì)只讀屬性賦值
"use strict";
var obj = {};
Object.defineProperty(obj, "x", {value:1, writable:false});
console.log(obj); // 輸出{x: 1}
obj.x = 3.14; // 報(bào)錯(cuò)
3.1.4.9 不允許對(duì)一個(gè)使用getter方法讀取的屬性進(jìn)行賦值
"use strict";
var obj = {get x() {return 0} };
obj.x = 3.14; // 報(bào)錯(cuò)
3.1.4.10 不允許刪除一個(gè)不允許刪除的屬性
"use strict";
delete Object.prototype; // 報(bào)錯(cuò)
3.1.4.11 變量名不能使用 "eval" 字符串
"use strict";
var eval = 3.14; // 報(bào)錯(cuò)
3.1.4.12 變量名不能使用 "arguments" 字符串:
"use strict";
var arguments = 3.14; // 報(bào)錯(cuò)
3.1.4.13 全局的'use strict',函數(shù)內(nèi)的變量也聲明
"use strict";
myFunction();
function myFunction() {
y = 3.14; // 報(bào)錯(cuò) (y 未定義)
}
3.1.4.14 函數(shù)內(nèi)部聲明是局部作用域 (只在函數(shù)內(nèi)使用嚴(yán)格模式):
x = 3.14; // 不報(bào)錯(cuò)
myFunction();
function myFunction() {
"use strict";
y = 3.14; // 報(bào)錯(cuò) (y 未定義)
}
3.1.4.4 為什么使用嚴(yán)格模式:
消除Javascript語法的一些不合理、不嚴(yán)謹(jǐn)之處,減少一些怪異行為;
消除代碼運(yùn)行的一些不安全之處,保證代碼運(yùn)行的安全;
提高編譯器效率,增加運(yùn)行速度;
為未來新版本的Javascript做好鋪墊。
"嚴(yán)格模式"體現(xiàn)了Javascript更合理、更安全、更嚴(yán)謹(jǐn)?shù)陌l(fā)展方向,包括IE 10在內(nèi)的主流瀏覽器,都已經(jīng)支持它,許多大項(xiàng)目已經(jīng)開始全面擁抱它。
3.2、解構(gòu)賦值(案例:lesson2-jiegou.js)
解構(gòu)賦值的分類:數(shù)組解構(gòu)賦值、對(duì)象解構(gòu)賦值、字符串解構(gòu)賦值、布爾值解構(gòu)賦值、函數(shù)參數(shù)解構(gòu)賦值、數(shù)值解構(gòu)賦值
3.2.1、數(shù)組解構(gòu)賦值
// 塊作用域:變量的重復(fù)聲明,用塊包起來就不會(huì)出現(xiàn)問題
{}
{
let a, b, rest;
[a, b] = [1, 2];
// 輸出1 2
console.log(a, b);
}
{
let a, b, rest;
[a,b,...rest]=[1,2,3,4,5,6]
// 輸出1 2 [3,4,5,6]
console.log(a,b,rest);
}
3.2.1.1、默認(rèn)值undefined
// 沒有配對(duì)成功,默認(rèn)值為3;如果=3去掉,c是undefined
{
let a, b, c, rest;
[a, b, c=3] = [1, 2];
// 輸出1 2 3
console.log(a, b, c);
}
3.2.1.2、使用場(chǎng)景
// 變量交換
{
let a = 1;
let b = 2;
[a, b] = [b, a];
// 輸出2 1
console.log(a, b)
}
// 取值方便
{
function f() {
return [1,2]
}
let a, b;
[a,b]=f();
// 輸出1 2
console.log(a, b)
}
// 選擇性接收變量
{
function f() {
return [1,2,3,4,5]
}
let a,b,c;
// 兩個(gè)逗號(hào),對(duì)應(yīng)一個(gè)值
[a,,,b]=f();
// 輸出1 4
console.log(a, b)
}
{
function f() {
return [1,2,3,4,5]
}
let a,b,c;
[a,...b]=f();
// 輸出1 [2,3,4,5]
console.log(a, b)
}
3.2.2、對(duì)象解構(gòu)賦值
// 左側(cè)與右側(cè)都是一個(gè)對(duì)象
{
let a,b;
({a, b} = {a:1,b:2});
// 輸出1 2
console.log(a,b)
}
{
let o={p:42,q:true};
let {p,q}=o;
// 輸出:42 true
console.log(p,q);
}
3.2.2.1、默認(rèn)值
{
let {a = 10, b = 5} = {a: 3};
// 輸出:3 5
console.log(a, b);
}
3.2.2.2、使用場(chǎng)景
// 獲取json
{
let metaData = {
title: 'abc',
test:[{
title:'test',
desc:'description'
}]
}
let {title:esTitle,test:[{title:cnTitle}]} = metaData;
// 輸出:abc test
console.log(esTitle, cnTitle)
}
3.3、正則(案例:lesson3-regexp.js)略
新特性:構(gòu)造函數(shù)的變化、正則方法的擴(kuò)展、u修飾符、y修飾符、s修飾符
{
// es5
let regex = new RegExp('xyz','i');
let regex2 = new RegExp(/xyz/i);
// 輸出:true true
console.log(regex.test('xyz123'), regex2.test('xyz123'));
// es6
// 允許第二個(gè)參數(shù)i覆蓋修飾符ig
let regex3 = new RegExp(/xyz/ig,'i');
console.log(regex3.flags)
}
// y修飾符
{
let s = 'bbb_bb_b';
// g跟y都是全局匹配;但是全局匹配不同點(diǎn)是,g是從上一次匹配繼續(xù)開始查找(只要能找到,就算匹配成功)
// y是從下一個(gè)匹配,如果第一個(gè)匹配不對(duì),就算匹配失敗
// 第一步g跟y都可以匹配到bbb
// 第二步只有g(shù)可以匹配到bb
let a1 = /b+/g;
let a2 = /b+/y;
console.log('one',a1.exec(s),a2.exec(s));
console.log('two',a1.exec(s),a2.exec(s));
// 判斷一個(gè)正則是否使用了y修飾符
console.log(a1.sticky);
console.log(a2.sticky);
}
// u修飾符(1、當(dāng)處理字符串中的正則的長(zhǎng)度大于2的時(shí)候 2、.是修飾小于2個(gè)字節(jié))
{
// true: \uD83D\uDC2A當(dāng)成了2個(gè)字母(字符)
console.log('u-1',/^\uD83D/.test('\uD83D\uDC2A'));
// false: \uD83D\uDC2A當(dāng)成了1個(gè)字母(字符)
console.log('u-2',/^\uD83D/u.test('\uD83D\uDC2A'));
// 如果{}放的是unicode編碼,要加個(gè)u,才能被識(shí)別
// false
console.log(/\u{61}/.test('a'));
// true
console.log(/\u{61}/u.test('a'));
// ??
console.log(`\u{20BB7}`);
let s = '??';
// false
console.log('u',/^.$/.test(s))
// true
console.log('u',/^.$/u.test(s))
// false
console.log('test',/??{2}/.test('????'));
// true
console.log('test-2',/??{2}/u.test('????'));
}
3.4、字符串(案例:lesson4-string.js)
新增特性:Unicode表示法、遍歷接口、模板字符串、新增方法(10種)
npm install babel-polyfill --save-dev
label-polyfill.png
{
let str = 'string';
// 查找是否包含了r
console.log('查找是否包含了r:', str.includes('r')); // true
// 判斷是否以str為起始
console.log('判斷是否以str為起始:',str.startsWith('str')); // true
// 判斷是否以ng為結(jié)尾
console.log('判斷是否以ng為結(jié)尾:',str.endsWith('ng')); // true
}
{
let str = 'abc';
// 字符串復(fù)制
console.log('字符串復(fù)制:' + str.repeat(2)); // abcabc
}
{
let name = 'list';
let info = 'hello world';
let m = `i am ${name},${info}`;
console.log('字符串拼接:' + m) // i am list,hello world
}
{
// 通常運(yùn)用在日期
// 向前補(bǔ):長(zhǎng)度是4位,不夠補(bǔ)0
console.log('1'.padStart(4,'0')); // 0001
// 向后補(bǔ)
console.log('1'.padEnd(2,'0')); // 10
}
3.5 數(shù)值擴(kuò)展(案例:lesson5-number-math.js)
新增特性:新增方法、方法調(diào)用
{
// Number.isFinite()用來檢查一個(gè)數(shù)值是否為有限的
// 有進(jìn) true
console.log('15',Number.isFinite(15));
// 無進(jìn) false
console.log('NaN',Number.isFinite(NaN));
// 分母為0 false
console.log('1/0',Number.isFinite('true'/0));
// true
console.log('NaN',Number.isNaN(NaN));
// false
console.log('0',Number.isNaN(0));
}
{
// 判斷一個(gè)數(shù)是不是整數(shù)
// true
console.log('判斷25是不是整數(shù):' + Number.isInteger(25));
// true
console.log('判斷25.0數(shù)是不是整數(shù):' + Number.isInteger(25.0));
// false
console.log('判斷25.1數(shù)是不是整數(shù):' + Number.isInteger(25.1));
// false
console.log('判斷"25.1"數(shù)是不是整數(shù):' + Number.isInteger('25.1'));
// false
console.log('判斷"25"數(shù)是不是整數(shù):' + Number.isInteger('25'));
}
{
// 常量
// 表示數(shù)的最大上線 9007199254740991
console.log(Number.MAX_SAFE_INTEGER);
// 表示數(shù)的最小下線 -9007199254740991
console.log(Number.MIN_SAFE_INTEGER);
// 10是一個(gè)安全的數(shù) true
console.log('10', Number.isSafeInteger(10));
// false
console.log('a', Number.isSafeInteger('a'));
}
{
// Math.trunc取整數(shù)
// 4
console.log(4.1,Math.trunc(4.1));
// 4
console.log(4.9,Math.trunc(4.9));
}
{
// 判斷數(shù)字是正數(shù)還是負(fù)數(shù)
// 負(fù)數(shù)為-1
console.log('-5',Math.sign(-5));
// 0為0
console.log('0',Math.sign(0));
// 正數(shù)為1
console.log('5',Math.sign(5));
// NaN
console.log('foo',Math.sign('foo'));
}
{
// -1的立方根
console.log('-1的立方根:',Math.cbrt(-1))
console.log('8的立方根:',Math.cbrt(8))
}
3.6 數(shù)組擴(kuò)展(案例:lesson6-array.js)
新增特性:Array.from、Array.of、copyWithin、find\findIndex、fill、entries\keys\values、inludes
{
// 是一個(gè)數(shù)組
let arr = Array.of(3,4,7,9,11);
console.log('arr是一個(gè)數(shù)組' + arr); // 3,4,7,9,11
// 空數(shù)組
let empty = Array.of();
console.log('空數(shù)組:',empty); // 空數(shù)組: []
}
{
let p = document.querySelectorAll('p');
let pArr = Array.from(p);
pArr.forEach(function (item) {
// textContent原生js獲取DOM節(jié)點(diǎn)內(nèi)容
// es6
// hjy
// oli
console.log(item.textContent);
});
// 把數(shù)組的里參數(shù)都乘以2
console.log(Array.from([1,3,5],function (item) {
return item*2; // 2,6,10
}));
}
{
// 數(shù)組里的參數(shù)都被替換成7
console.log('fill-7',[1,'a',undefined].fill(7)); // [7, 7, 7]
// 從起始位置1,不到3的位置,替換成7
console.log('fill,post',['a','b','c'].fill(7,1,3)); // ["a", 7, 7]
}
{
for(let index of ['1','c','ks'].keys()){
// 0 1 2
console.log('keys', index);
}
for(let value of ['1','c','ks'].values()){
// 1 c ks
console.log('values', value);
}
for(let [index,value] of ['1','c','ks'].entries()){
// index=0, value=1
// index=1, value=c
// index=2, value=ks
console.log('index=' + index + ', value=' + value);
}
}
{
// Array.prototype.copyWithin(target, start = 0, end = this.length)
// target(必需):從該位置開始替換數(shù)據(jù)。如果為負(fù)值,表示倒數(shù)。
// start(可選):從該位置開始讀取數(shù)據(jù),默認(rèn)為 0。如果為負(fù)值,表示倒數(shù)。
// end(可選):到該位置前停止讀取數(shù)據(jù),默認(rèn)等于數(shù)組長(zhǎng)度。如果為負(fù)值,表示倒數(shù)。
// 從0的位置開始替換,從3開始讀取,從4截止
// 把4放到1的位置上:[4, 2, 3, 4, 5]
console.log([1,2,3,4,5].copyWithin(0,3,4));
}
{
console.log([1,2,3,4,5,6].find(function (item) {
// 查找第一個(gè)符合大于3的值(找到了就停止)
// 返回4
return item > 3;
}));
console.log([1,2,3,4,5,6].findIndex(function (item) {
// 查找第一個(gè)符合大于3的下標(biāo)(找到了就停止)
// 返回3
return item > 3;
}));
}
{
// 數(shù)組中是不是包含了1
// true
console.log('number',[1,2,NaN].includes(1));
// true
console.log('number',[1,2,NaN].includes(NaN));
}
3.7 函數(shù)擴(kuò)展(案例:lesson7-function.js)
新增特性:參數(shù)默認(rèn)值、rest參數(shù)、擴(kuò)展運(yùn)算符、箭頭函數(shù)、this綁定、尾調(diào)用
{
function test(x,y = 'world') {
// 如果y沒有值,就采用默認(rèn)值為world;如果有值,用采用傳遞過來的參數(shù)
console.log('默認(rèn)值',x,y)
}
test('hello');
test('hello','hjy');
// 錯(cuò)誤寫法:
// function test(x,y = 'world',c)
// 正確寫法:
// function test(x,y = 'world',c='bb')
}
{
let x = 'test';
// 都是取kill
function test2(x,y=x) {
console.log("作用域:",x,y);
}
// 作用域: kill kill
test2('kill');
function test3(c,y=x) {
// 作用域: kill test
console.log("作用域:",c,y);
}
test3('kill');
}
{
// ...arg不確定傳入幾個(gè)參數(shù),轉(zhuǎn)成一個(gè)數(shù)組
function test4(...arg) {
for(let v of arg){
// rest 1
// rest 2
// rest 3
// rest 4
// rest a
console.log('rest',v);
}
}
test4(1,2,3,4,'a');
}
{
// 把數(shù)組轉(zhuǎn)成一個(gè)離散的值
console.log(...[1,2,4]); // 1 2 4
console.log('a',...[1,2,4]);// a 1 2 4
}
{
// 函數(shù)
// arrow函數(shù)名 v參數(shù) v*2返回值
let arrow = v => v*2;
let arrow2 = () => 5;
console.log('a',arrow(3)); // a 6
console.log('a',arrow2()); // a 5
}
{
// 尾調(diào)用(提升性能:函數(shù)地址嵌套)
function tail(x) {
console.log('tail',x);
}
function fx(x) {
return tail(x)
}
fx(123)
}
3.8 對(duì)象擴(kuò)展(案例:lesson8-Obj.js)
新增特性:簡(jiǎn)潔表示法、屬性表達(dá)式、擴(kuò)展運(yùn)算符、Object新增方法
{
// 簡(jiǎn)潔表達(dá)
let o = 1;
let k = 2;
let es5 = {
o:o,
k:k
};
let es6 = {
o,
k
};
console.log(es5,es6); // {o: 1, k: 2} {o: 1, k: 2}
// 對(duì)象里有方法
let es5_method = {
hello:function () {
console.log('hello');
}
};
let es6_method = {
hello(){
console.log('hello');
}
};
console.log(es5_method.hello(),es6_method.hello());// hello hello
}
{
// 屬性表達(dá)式
let a = 'b';
let es5_obj = {
a:'c'
};
// [a]是一個(gè)變量
let es6_obj = {
[a]:'c'
};
// {a: "c"} {b: "c"}
console.log(es5_obj,es6_obj)
}
{
// 新增API
// Object.is與三個(gè)等號(hào)相同 輸出:true true
console.log('判斷2個(gè)字符串是否相等', Object.is('abc','abc'), 'abc' === 'abc');
// 數(shù)組是引用類型,但是數(shù)組引用的是不同地址 輸出:false false
console.log('數(shù)組',Object.is([],[]), [] === []);
// 當(dāng)個(gè)對(duì)象合并成一個(gè)對(duì)象{a: "a", b: "b"}
console.log('拷貝', Object.assign({a:'a'}, {b:'b'}));
// 對(duì)數(shù)組進(jìn)行遍歷
let test = {k:123,o:456};
for(let [key,value] of Object.entries(test)){
console.log(key,value);
}
}
3.9 symbol(案例:lesson9-symbol.js)
ES6新增加的類型
就是這種數(shù)據(jù)類型,提供一個(gè)獨(dú)一無二(保證唯一)的值
{
// 聲明
let a1 = Symbol();
let a2 = Symbol();
// false
console.log(a1 === a2);
// 'a3'是一個(gè)key值
let a3 = Symbol.for('a3');
let a4 = Symbol.for('a3');
// true
console.log(a3 === a4);
}
{
// 使用場(chǎng)景:兩個(gè)相同的名字,不想去改變
let a1 = Symbol.for('abc');
let obj = {
[a1]:'123',
'abc':'345',
'c':456
};
console.log(obj); // {abc: "345", c: 456, Symbol(abc): "123"}
// symbol的值取不到
for(let [key,value] of Object.entries(obj)){
// let of abc 345
// let of c 456
console.log('let of', key, value);
}
// 取到symbol的值
Object.getOwnPropertySymbols(obj).forEach(function (item) {
// 123
console.log(obj[item])
});
// 兩種參數(shù)的值都可以獲取到
Reflect.ownKeys(obj).forEach(function (item) {
// ownKeys abc 345
// ownKeys c 456
// ownKeys Symbol(abc) 123
console.log('ownKeys', item, obj[item]);
})
}
3.10 set-map數(shù)據(jù)結(jié)構(gòu)(案例:lesson10-set-map.js)
{
let list = new Set();
list.add(5);
list.add(7);
// 判斷長(zhǎng)度 輸出:2
console.log('size',list.size);
}
{
let arr = [1,2,3,4,5];
let list = new Set(arr);
// 5
console.log('size', list.size);
}
{
// 運(yùn)用場(chǎng)景:去重
let list = new Set();
list.add(1);
list.add(2);
// 重復(fù)元素,沒有添加成功
list.add(1);
// {1, 2}
console.log('list',list);
let arr = [1,2,3,1,2];
let list2 = new Set(arr);
// 輸出{1,2,3}
console.log('unique',list2);
}
{
let arr = ['add','delete','clear','has'];
let list = new Set(arr);
// 判斷l(xiāng)ist里面有沒有add這個(gè)值 輸出:true
console.log('has', list.has('add'));
// 刪除list
console.log('delete', list.delete('add'), list);
// 清空list
list.clear();
console.log('list',list);
}
{
let arr = ['add','delete','clear','has'];
let list = new Set(arr);
for(let key of list.keys()){
// keys add
// keys delete
// keys clear
// keys has
console.log('keys',key);
}
for(let value of list.values()){
// values add
// values delete
// values clear
// values has
console.log('values',value);
}
for(let value of list){
// values add
// values delete
// values clear
// values has
console.log('values',value);
}
for(let [key,value] of list.entries()){
// entries add add
// entries delete delete
// entries clear clear
// entries has has
console.log('entries',key,value)
}
list.forEach(function (item) {
// add
// delete
// clear
// has
console.log(item);
})
}
{
// 和set的數(shù)據(jù)類型不一樣,WeakSet只是能對(duì)象,不能是數(shù)值,例如boolean
// WeakSet對(duì)象這塊,弱引用(不會(huì)檢測(cè)對(duì)象在其他地方引用到,意味著不會(huì)跟垃圾回收機(jī)制掛鉤到,簡(jiǎn)單說:WeakSet是一個(gè)地址的引用)
// WeakSet沒有clean、沒有set、不能遍歷
let weakList = new WeakSet();
let arg = {};
weakList.add(arg);
// 報(bào)錯(cuò)
// weakList.add(2);
console.log('weakList',weakList);
}
{
let map = new Map();
let arr = ['123'];
map.set(arr,456);
console.log('map', map, map.get(arr)); // key是123 value是456
}
{
let map = new Map([['a',123],['b',456]]);
console.log('map args', map); // {"a" => 123, "b" => 456}
console.log('size', map.size); // 2
console.log('delete', map.delete('a'), map); // {"b" => 456}
console.log('clear', map.clear(), map); // {}
}
{
// 與set和weakSet是一樣的
let weakmap = new WeakMap();
}
3.11 map-set與數(shù)組和對(duì)象的比較(案例:lesson11-map-set-array-obj.js)
涉及的數(shù)據(jù)結(jié)構(gòu)能使用map,不使用數(shù)組
數(shù)據(jù)的唯一性使用set
{
// map 和 array 數(shù)據(jù)結(jié)構(gòu)橫向?qū)Ρ龋涸鰟h改查
let map = new Map();
let array = [];
// 增
map.set('t',1);
array.push({t:1});
console.info('map-array-add',map,array);
// 查
let map_exist = map.has('t');// true
let array_exist = array.find(item=>item.t);// 遍歷數(shù)組,查看是否存在;如果存在,就返回值
console.info('map-array-find', map_exist, array_exist);
// 改(map比較簡(jiǎn)單,array復(fù)雜)
map.set('t',2);
array.forEach(item => item.t ? item.t = 2 : '');
console.info('map-array-modify',map, array);
// 刪(map比較簡(jiǎn)單,array復(fù)雜)
map.delete('t');
let index = array.findIndex(item => item.t);
array.splice(index,1);
console.info('map-array-remove',map, array);
}
{
// set 和 array 的對(duì)比
let set = new Set();
let array = [];
// 增
set.add({t:1});
array.push({t:1});
console.info('set-array-add', set, array);
// 查
let set_exist = set.has({t:1});// false
let array_exist = array.find(item=>item.t);// 遍歷數(shù)組,查看是否存在;如果存在,就返回值
console.info('set-array-find', set_exist, array_exist);
// 改
set.forEach(item => item.t ? item.t=2 :'');
array.forEach(item => item.t ? item.t=2 :'');
console.info('set-array-modify', set, array);
// 刪(set和array刪除都相對(duì)麻煩)
set.forEach(item => item.t ? set.delete(item) : '');
let index = array.findIndex(item => item.t);
array.splice(index, 1);
console.info('set-array-remove', set, array);
}
{
// set map 和 object 對(duì)比
let item = {t:1};
let map = new Map();
let set = new Set();
let obj = {};
// 增
map.set('t',1);
set.add(item);
obj['t'] = 1;
console.info('map-set-obj', obj, map, set);
// 查(obj不如map和set語義化)
console.info({
map_find:map.has('t'),
set_find:set.has(item),
obj_find:'t' in obj
});
// 改
map.set('t',2);
item.t = 2;
obj['t'] = 2;
console.log('map-set-obj-modify', obj, map, set);
// 刪(set和array刪除都相對(duì)麻煩)
map.delete('t');
set.delete(item);
delete obj['t'];
console.log('map-set-obj-remove', obj, map, set);
}
3.12 Proxy 和 Reflect(案例:lesson12-proxy-reflect.js)
Proxy代理,代理商:用戶 和 商家(連接了用戶和最真實(shí)對(duì)象的一個(gè)層)
Reflect反射
{
// 供應(yīng)商 原始對(duì)象,存儲(chǔ)真實(shí)數(shù)據(jù)
let obj = {
time:'2017-03-11',
name:'net',
_r:123
};
// 代理商
let monitor = new Proxy(obj, {
// 攔截(代理)對(duì)象屬性的讀取
get(target, key){
// target相當(dāng)于obj
// console.log(target);
// 把2017替換成2018
return target[key].replace('2017','2018');
},
// 攔截對(duì)象設(shè)置屬性
set(target, key, value){
if(key === 'name'){
return target[key] = value
}else {
return target[key];
}
},
// 攔截key in object 操作
has(target, key){
if(key === 'name'){
return target[key]
}else{
return false;
}
},
// 攔截delete
deleteProperty(target,key){
if(key.indexOf('_') > -1){
delete target[key];
return true;
}else{
return target[key];
}
},
// 攔截Object.keys, Object.getOwnPropertySymbols, Object.getOwnPropertyNames
// 保護(hù)time的key不被用戶看到
ownKeys(target){
return Object.keys(target).filter(item=>item!='time')
}
});
console.log('get', monitor.time); // 2018-03-11
monitor.time = '2019';
monitor.name = 'hjy';
console.log('set',monitor.time); // 2018-03-11
console.log('set',monitor.name); // hjy
// time被攔截了 true false
console.log('has','name' in monitor, 'time' in monitor);
// 對(duì)象依舊存在
// delete monitor.time;
// console.log('delete', monitor);
// 成功的刪掉_r
// delete monitor._r;
// console.log('delete', monitor);
console.log('ownKeys',Object.keys(monitor));
}
{
let obj = {
time:'2017-03-11',
name:'net',
_r:123
};
// 讀取time的值
console.log('Reflect get', Reflect.get(obj,'time')); // 2017-03-11
// 把name改成hjy
Reflect.set(obj, 'name', 'hjy');
console.log(obj); // {time: "2017-03-11", name: "hjy", _r: 123}
// 判斷obj里是否有name
console.log('has',Reflect.has(obj,'name')); // true
}
{
function validator(target, validator) {
// 對(duì)target進(jìn)行代理
return new Proxy(target,{
// 保存配置選項(xiàng)
_validator:validator,
// 對(duì)set進(jìn)行修改
set(traget,key,value,proxy){
if(target.hasOwnProperty(key)){
let va = this._validator[key];
if(!!va(value)){
return Reflect.set(target,key,value,proxy);
}else{
throw Error(`不能設(shè)置${key}到${value}`)
}
}else{
throw Error(`${key} 不存在`)
}
}
})
}
const personValidators={
name(val){
return typeof val === 'string'
},
age(val){
return typeof val === 'number' && val > 18
}
};
class Person{
constructor(name,age){
this.name = name;
this.age = age;
return validator(this,personValidators)
}
}
const person = new Person('hjy',30);
console.log(person);
// 不能設(shè)置數(shù)字
// person.name = 48;
person.name = 'oli';
console.log(person);
}
3.13 類 和 對(duì)象(案例:lesson13-class.js)
類的概念:基本語法、類的繼承、靜態(tài)方法、靜態(tài)屬性、getter、setter
{
// 基本定義和生成實(shí)例
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
let v_parent = new Parent('v');
let v_parent2 = new Parent();
// {name: "v"}
console.log('構(gòu)造函數(shù)和實(shí)例',v_parent);
// {name: "hjy"}
console.log('構(gòu)造函數(shù)和實(shí)例',v_parent2);
}
{
// 繼承
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
class Child extends Parent{
}
// {name: "hjy"}
console.log('繼承', new Child());
}
{
// 繼承傳遞參數(shù)
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
class Child extends Parent{
constructor(name='child'){
// 修改父類的參數(shù)(要把super放在第一行)
super(name);
// 子類增加自己的屬性
this.type='childType';
}
}
// {name: "lio", type: "childType"}
console.log('子類向父類傳遞參數(shù)', new Child('lio'));
}
{
// getter setter
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
get longName(){
return '姓名:' + this.name
}
set longName(value){
this.name = value;
}
}
let v = new Parent();
// hjy
console.log('getter',v.longName);
v.longName='lio';
// lio
console.log('setter',v.longName);
}
{
// 靜態(tài)方法(通過類調(diào)用,而不是通過類的實(shí)例去調(diào)用)
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
// 靜態(tài)方法
static tell(){
console.log('tell');
}
}
// tell
Parent.tell();
}
{
// 靜態(tài)屬性
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
// 靜態(tài)方法(不能定義靜態(tài)屬性)
static tell(){
console.log('tell');
}
}
// 靜態(tài)屬性
Parent.type = 'test';
// tell
console.log('靜態(tài)屬性',Parent.type);
}
3.14 Promise(案例:lesson14-promise.js)
異步編程的解決方法
A執(zhí)行完再執(zhí)行B,兩種實(shí)現(xiàn)方式:回調(diào)、事件觸發(fā)
{
// es5回調(diào)解決異步操作
let ajax = function (callback) {
console.log('執(zhí)行');
setTimeout(function () {
// 判斷回調(diào)是不是存在,如果存在,執(zhí)行下一步
callback && callback.call()
},1000)
};
ajax(function () {
console.log('timeout1');
});
}
{
// es6
let ajax = function () {
console.log('執(zhí)行2');
// 返回一個(gè)Promise實(shí)例(執(zhí)行下一步功能)
// resolve執(zhí)行下一步操作
// reject中斷下一步操作
return new Promise(function (resolve,reject) {
setTimeout(function () {
resolve();
},1000);
})
};
ajax().then(function () {
console.log('promise','timeout2');
})
}
{
// A執(zhí)行完再執(zhí)行B,B執(zhí)行完了執(zhí)行C ...
let ajax = function () {
console.log('執(zhí)行3');
// 返回一個(gè)Promise實(shí)例(執(zhí)行下一步功能)
// resolve執(zhí)行下一步操作
// reject中斷下一步操作
return new Promise(function (resolve,reject) {
setTimeout(function () {
resolve();
},1000);
})
};
ajax().then(function () {
return new Promise(function (resolve,reject) {
// 又可以下一步
resolve();
},2000)
}).then(function () {
console.log('timeout3');
})
}
{
// catch捕獲錯(cuò)誤
let ajax = function (num) {
console.log('執(zhí)行4');
return new Promise(function (resolve,reject) {
// 如果大于5,執(zhí)行下一步
if(num > 5){
resolve();
}else{
// 拋出錯(cuò)誤
throw new Error('出錯(cuò)了');
}
})
};
ajax(6).then(function () {
console.log('log',6);
}).catch(function (err) {
console.log('catch',err);
});
ajax(3).then(function () {
console.log('log',3);
}).catch(function (err) {
console.log('catch',err);
})
}
{
// 所有圖片加載完再添加到頁面
function loadImg(src) {
return new Promise((resolve,reject) => {
let img = document.createElement('img');
img.src = src;
// 圖片加載完
img.onload=function () {
resolve(img);
};
// 圖片加載失敗
img.onerror = function (err) {
reject(err);
};
})
}
function showImgs(imgs) {
imgs.forEach(function (img) {
document.body.appendChild(img);
})
}
// all:把多個(gè)Promise實(shí)例當(dāng)成一個(gè)Promise實(shí)例
Promise.all([
// 三張圖片都加載完,才會(huì)觸發(fā)all,才執(zhí)行then
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg')
]).then(showImgs)
}
{
// 有一個(gè)圖片加載完成添加到頁面
function loadImg(src) {
return new Promise((resolve,reject) => {
let img = document.createElement('img');
img.src = src;
// 圖片加載完
img.onload=function () {
resolve(img);
};
// 圖片加載失敗
img.onerror = function (err) {
reject(err);
};
})
}
function showImgs(img) {
let p = document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
// 三張圖片,只要有一個(gè)圖片加載出來,那個(gè)就先顯示在頁面上
Promise.race([
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg')
]).then(showImgs)
}
3.15 Iterator(案例:lesson15-iterator.js)
操作數(shù)組、object、map、set
{
let arr = ['hello','world'];
let map = arr[Symbol.iterator]();
// {value: "hello", done: false}
console.log(map.next());
// {value: "world", done: false}
console.log(map.next());
// {value: undefined, done: true} true代表沒有下一步
console.log(map.next());
}
{
// 自定義iterator接口
// obj數(shù)據(jù)是我們自己填充
let obj = {
start:[1,3,2],
end:[7,9,8],
// Symbol.iterator變量名
[Symbol.iterator](){
let self = this;
// 記錄當(dāng)前遍歷索引
let index = 0;
// start和end合并成一個(gè)數(shù)組
let arr = self.start.concat(self.end);
// 記錄數(shù)組的長(zhǎng)度
let len = arr.length;
return {
next(){
if(index < len){
return {
value:arr[index++],
done:false
}
} else {
return {
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.log(key);
}
}
{
// 對(duì)數(shù)組進(jìn)行遍歷
let arr = ['hello','world'];
for(let value of arr){
// hello
// world
console.log('value',value);
}
}
3.16 Generator(案例:lesson16-decorators.js)
異步編程的一種解決方案
{
// genertaor基本定義
// 與普通的函數(shù)不同:* 、 yield
let tell = function* () {
yield 'a';
yield 'b';
return 'c';
};
// 調(diào)用tell,執(zhí)行到第一個(gè)yield停止下來
let k = tell();
// 執(zhí)行第一個(gè)yield
// {value: "a", done: false}
console.log(k.next());
// 執(zhí)行第二個(gè)yield
// {value: "b", done: false}
console.log(k.next());
// 執(zhí)行retrun
// {value: "c", done: true}
console.log(k.next());
// {value: undefined, done: true}
console.log(k.next());
}
{
// of遍歷
let obj = {
};
obj[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
for(let value of obj){
// 1
// 2
// 3
console.log('value',value);
}
}
{
let state = function* () {
while(1){
yield 'A';
yield 'b';
yield 'c';
}
}
let status = state();
// {value: "A", done: false}
// {value: "b", done: false}
// {value: "c", done: false}
// {value: "A", done: false}
// {value: "b", done: false}
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
}
{
// 抽獎(jiǎng)
let draw = function (count) {
// 具體抽獎(jiǎng)邏輯
console.info(`剩余${count}次`);
};
let residue = function* (count) {
while (count > 0){
count--;
yield draw(count);
}
};
// 可以抽獎(jiǎng)5次,如果是最后一次,點(diǎn)擊無效
let star = residue(5);
let btn = document.createElement('button');
btn.id = 'start';
btn.textContent = '抽獎(jiǎng)';
document.body.appendChild(btn);
document.getElementById('start').addEventListener('click',function () {
star.next();
},false)
}
{
// 長(zhǎng)輪詢(接口請(qǐng)求失敗,一直請(qǐng)求)
let ajax = function* () {
yield new Promise(function (resolve,reject) {
// 接口
setTimeout(function () {
resolve({code:0})
},200);
})
};
let pull = function () {
let genertaor = ajax();
let step = genertaor.next();
step.value.then(function (d) {
if(d.code != 0){
setTimeout(function () {
console.log('wait');
pull();
},1000);
}else{
console.log(d);
}
})
};
pull();
}
3.17 Decorator(案例:lesson17-decorators.js)
修飾器:是一個(gè)函數(shù),修改類的行為(擴(kuò)展類的動(dòng)能,只在類里修改有用)
{
// 是一個(gè)函數(shù)
let readonly = function (target, name, descriptor) {
descriptor.writable = false;
return descriptor
};
// 修改類的行為
class Test{
// 加了修飾器,就是不能重新修改參數(shù);只有只讀的狀態(tài)
// @readonly與上面的readonly要一致
@readonly
time(){
return '2017-03-11'
}
}
let test = new Test();
// 加了修飾器,就是不能重新修改參數(shù);只有只讀的狀態(tài)
// 報(bào)錯(cuò)
// test.time = function () {
// console.log('reset name')
// }
// 2017-03-11
console.log(test.time())
}
{
let typename = function (target,name,descriptor) {
// 靜態(tài)屬性
target.myname = 'hello';
};
// 修飾器(對(duì)類進(jìn)行修飾)
@typename
class Test{
}
console.log('類修飾符',Test.myname); // hello
// 第三方庫修飾器的js庫:core-decorators; npm install core-decorators
}
{
// 看廣告是show還是click
let log = (type) => {
return function (target,name,descriptor) {
let src_method = descriptor.value;
// 方法重新賦值
descriptor.value=(...arg)=>{
src_method.apply(target,arg);
console.info(`log ${type}`);
}
}
}
class AD{
@log('show')
show(){
console.info('ad is show');
}
@log('click')
click(){
console.info('ad is click');
}
}
// 實(shí)例化
let ad = new AD();
ad.show();
ad.click();
}
3.18 模塊化(案例:lesson18-module.js)
let A = 123;
let test = function () {
console.log('test');
}
class Hello{
test(){
console.log('class');
}
}
export default {
A,
test,
Hello
}
// 模塊化:導(dǎo)入所有 lesson只是一個(gè)別名
import * as lesson from './class/lesson18-module';
console.log(lesson.A);
console.log(lesson.test);
import Lesson18 from './class/lesson18-module';
console.log(Lesson18.A);
"use strict";
var x = 3.14;
delete x; // 報(bào)錯(cuò)
"use strict";
function x(p1, p2) {};
delete x; // 報(bào)錯(cuò)
"use strict";
function x(p1, p1) {}; // 報(bào)錯(cuò)
"use strict";
var x = 010; // 報(bào)錯(cuò)
"use strict";
var x = \010; // 報(bào)錯(cuò)
"use strict";
var obj = {};
Object.defineProperty(obj, "x", {value:1, writable:false});
console.log(obj); // 輸出{x: 1}
obj.x = 3.14; // 報(bào)錯(cuò)
"use strict";
var obj = {get x() {return 0} };
obj.x = 3.14; // 報(bào)錯(cuò)
"use strict";
delete Object.prototype; // 報(bào)錯(cuò)
"use strict";
var eval = 3.14; // 報(bào)錯(cuò)
"use strict";
var arguments = 3.14; // 報(bào)錯(cuò)
"use strict";
myFunction();
function myFunction() {
y = 3.14; // 報(bào)錯(cuò) (y 未定義)
}
x = 3.14; // 不報(bào)錯(cuò)
myFunction();
function myFunction() {
"use strict";
y = 3.14; // 報(bào)錯(cuò) (y 未定義)
}
消除Javascript語法的一些不合理、不嚴(yán)謹(jǐn)之處,減少一些怪異行為;
消除代碼運(yùn)行的一些不安全之處,保證代碼運(yùn)行的安全;
提高編譯器效率,增加運(yùn)行速度;
為未來新版本的Javascript做好鋪墊。
"嚴(yán)格模式"體現(xiàn)了Javascript更合理、更安全、更嚴(yán)謹(jǐn)?shù)陌l(fā)展方向,包括IE 10在內(nèi)的主流瀏覽器,都已經(jīng)支持它,許多大項(xiàng)目已經(jīng)開始全面擁抱它。
解構(gòu)賦值的分類:數(shù)組解構(gòu)賦值、對(duì)象解構(gòu)賦值、字符串解構(gòu)賦值、布爾值解構(gòu)賦值、函數(shù)參數(shù)解構(gòu)賦值、數(shù)值解構(gòu)賦值
// 塊作用域:變量的重復(fù)聲明,用塊包起來就不會(huì)出現(xiàn)問題
{}
{
let a, b, rest;
[a, b] = [1, 2];
// 輸出1 2
console.log(a, b);
}
{
let a, b, rest;
[a,b,...rest]=[1,2,3,4,5,6]
// 輸出1 2 [3,4,5,6]
console.log(a,b,rest);
}
// 沒有配對(duì)成功,默認(rèn)值為3;如果=3去掉,c是undefined
{
let a, b, c, rest;
[a, b, c=3] = [1, 2];
// 輸出1 2 3
console.log(a, b, c);
}
// 變量交換
{
let a = 1;
let b = 2;
[a, b] = [b, a];
// 輸出2 1
console.log(a, b)
}
// 取值方便
{
function f() {
return [1,2]
}
let a, b;
[a,b]=f();
// 輸出1 2
console.log(a, b)
}
// 選擇性接收變量
{
function f() {
return [1,2,3,4,5]
}
let a,b,c;
// 兩個(gè)逗號(hào),對(duì)應(yīng)一個(gè)值
[a,,,b]=f();
// 輸出1 4
console.log(a, b)
}
{
function f() {
return [1,2,3,4,5]
}
let a,b,c;
[a,...b]=f();
// 輸出1 [2,3,4,5]
console.log(a, b)
}
// 左側(cè)與右側(cè)都是一個(gè)對(duì)象
{
let a,b;
({a, b} = {a:1,b:2});
// 輸出1 2
console.log(a,b)
}
{
let o={p:42,q:true};
let {p,q}=o;
// 輸出:42 true
console.log(p,q);
}
{
let {a = 10, b = 5} = {a: 3};
// 輸出:3 5
console.log(a, b);
}
// 獲取json
{
let metaData = {
title: 'abc',
test:[{
title:'test',
desc:'description'
}]
}
let {title:esTitle,test:[{title:cnTitle}]} = metaData;
// 輸出:abc test
console.log(esTitle, cnTitle)
}
新特性:構(gòu)造函數(shù)的變化、正則方法的擴(kuò)展、u修飾符、y修飾符、s修飾符
{
// es5
let regex = new RegExp('xyz','i');
let regex2 = new RegExp(/xyz/i);
// 輸出:true true
console.log(regex.test('xyz123'), regex2.test('xyz123'));
// es6
// 允許第二個(gè)參數(shù)i覆蓋修飾符ig
let regex3 = new RegExp(/xyz/ig,'i');
console.log(regex3.flags)
}
// y修飾符
{
let s = 'bbb_bb_b';
// g跟y都是全局匹配;但是全局匹配不同點(diǎn)是,g是從上一次匹配繼續(xù)開始查找(只要能找到,就算匹配成功)
// y是從下一個(gè)匹配,如果第一個(gè)匹配不對(duì),就算匹配失敗
// 第一步g跟y都可以匹配到bbb
// 第二步只有g(shù)可以匹配到bb
let a1 = /b+/g;
let a2 = /b+/y;
console.log('one',a1.exec(s),a2.exec(s));
console.log('two',a1.exec(s),a2.exec(s));
// 判斷一個(gè)正則是否使用了y修飾符
console.log(a1.sticky);
console.log(a2.sticky);
}
// u修飾符(1、當(dāng)處理字符串中的正則的長(zhǎng)度大于2的時(shí)候 2、.是修飾小于2個(gè)字節(jié))
{
// true: \uD83D\uDC2A當(dāng)成了2個(gè)字母(字符)
console.log('u-1',/^\uD83D/.test('\uD83D\uDC2A'));
// false: \uD83D\uDC2A當(dāng)成了1個(gè)字母(字符)
console.log('u-2',/^\uD83D/u.test('\uD83D\uDC2A'));
// 如果{}放的是unicode編碼,要加個(gè)u,才能被識(shí)別
// false
console.log(/\u{61}/.test('a'));
// true
console.log(/\u{61}/u.test('a'));
// ??
console.log(`\u{20BB7}`);
let s = '??';
// false
console.log('u',/^.$/.test(s))
// true
console.log('u',/^.$/u.test(s))
// false
console.log('test',/??{2}/.test('????'));
// true
console.log('test-2',/??{2}/u.test('????'));
}
新增特性:Unicode表示法、遍歷接口、模板字符串、新增方法(10種)
npm install babel-polyfill --save-dev

label-polyfill.png
{
let str = 'string';
// 查找是否包含了r
console.log('查找是否包含了r:', str.includes('r')); // true
// 判斷是否以str為起始
console.log('判斷是否以str為起始:',str.startsWith('str')); // true
// 判斷是否以ng為結(jié)尾
console.log('判斷是否以ng為結(jié)尾:',str.endsWith('ng')); // true
}
{
let str = 'abc';
// 字符串復(fù)制
console.log('字符串復(fù)制:' + str.repeat(2)); // abcabc
}
{
let name = 'list';
let info = 'hello world';
let m = `i am ${name},${info}`;
console.log('字符串拼接:' + m) // i am list,hello world
}
{
// 通常運(yùn)用在日期
// 向前補(bǔ):長(zhǎng)度是4位,不夠補(bǔ)0
console.log('1'.padStart(4,'0')); // 0001
// 向后補(bǔ)
console.log('1'.padEnd(2,'0')); // 10
}
新增特性:新增方法、方法調(diào)用
{
// Number.isFinite()用來檢查一個(gè)數(shù)值是否為有限的
// 有進(jìn) true
console.log('15',Number.isFinite(15));
// 無進(jìn) false
console.log('NaN',Number.isFinite(NaN));
// 分母為0 false
console.log('1/0',Number.isFinite('true'/0));
// true
console.log('NaN',Number.isNaN(NaN));
// false
console.log('0',Number.isNaN(0));
}
{
// 判斷一個(gè)數(shù)是不是整數(shù)
// true
console.log('判斷25是不是整數(shù):' + Number.isInteger(25));
// true
console.log('判斷25.0數(shù)是不是整數(shù):' + Number.isInteger(25.0));
// false
console.log('判斷25.1數(shù)是不是整數(shù):' + Number.isInteger(25.1));
// false
console.log('判斷"25.1"數(shù)是不是整數(shù):' + Number.isInteger('25.1'));
// false
console.log('判斷"25"數(shù)是不是整數(shù):' + Number.isInteger('25'));
}
{
// 常量
// 表示數(shù)的最大上線 9007199254740991
console.log(Number.MAX_SAFE_INTEGER);
// 表示數(shù)的最小下線 -9007199254740991
console.log(Number.MIN_SAFE_INTEGER);
// 10是一個(gè)安全的數(shù) true
console.log('10', Number.isSafeInteger(10));
// false
console.log('a', Number.isSafeInteger('a'));
}
{
// Math.trunc取整數(shù)
// 4
console.log(4.1,Math.trunc(4.1));
// 4
console.log(4.9,Math.trunc(4.9));
}
{
// 判斷數(shù)字是正數(shù)還是負(fù)數(shù)
// 負(fù)數(shù)為-1
console.log('-5',Math.sign(-5));
// 0為0
console.log('0',Math.sign(0));
// 正數(shù)為1
console.log('5',Math.sign(5));
// NaN
console.log('foo',Math.sign('foo'));
}
{
// -1的立方根
console.log('-1的立方根:',Math.cbrt(-1))
console.log('8的立方根:',Math.cbrt(8))
}
新增特性:Array.from、Array.of、copyWithin、find\findIndex、fill、entries\keys\values、inludes
{
// 是一個(gè)數(shù)組
let arr = Array.of(3,4,7,9,11);
console.log('arr是一個(gè)數(shù)組' + arr); // 3,4,7,9,11
// 空數(shù)組
let empty = Array.of();
console.log('空數(shù)組:',empty); // 空數(shù)組: []
}
{
let p = document.querySelectorAll('p');
let pArr = Array.from(p);
pArr.forEach(function (item) {
// textContent原生js獲取DOM節(jié)點(diǎn)內(nèi)容
// es6
// hjy
// oli
console.log(item.textContent);
});
// 把數(shù)組的里參數(shù)都乘以2
console.log(Array.from([1,3,5],function (item) {
return item*2; // 2,6,10
}));
}
{
// 數(shù)組里的參數(shù)都被替換成7
console.log('fill-7',[1,'a',undefined].fill(7)); // [7, 7, 7]
// 從起始位置1,不到3的位置,替換成7
console.log('fill,post',['a','b','c'].fill(7,1,3)); // ["a", 7, 7]
}
{
for(let index of ['1','c','ks'].keys()){
// 0 1 2
console.log('keys', index);
}
for(let value of ['1','c','ks'].values()){
// 1 c ks
console.log('values', value);
}
for(let [index,value] of ['1','c','ks'].entries()){
// index=0, value=1
// index=1, value=c
// index=2, value=ks
console.log('index=' + index + ', value=' + value);
}
}
{
// Array.prototype.copyWithin(target, start = 0, end = this.length)
// target(必需):從該位置開始替換數(shù)據(jù)。如果為負(fù)值,表示倒數(shù)。
// start(可選):從該位置開始讀取數(shù)據(jù),默認(rèn)為 0。如果為負(fù)值,表示倒數(shù)。
// end(可選):到該位置前停止讀取數(shù)據(jù),默認(rèn)等于數(shù)組長(zhǎng)度。如果為負(fù)值,表示倒數(shù)。
// 從0的位置開始替換,從3開始讀取,從4截止
// 把4放到1的位置上:[4, 2, 3, 4, 5]
console.log([1,2,3,4,5].copyWithin(0,3,4));
}
{
console.log([1,2,3,4,5,6].find(function (item) {
// 查找第一個(gè)符合大于3的值(找到了就停止)
// 返回4
return item > 3;
}));
console.log([1,2,3,4,5,6].findIndex(function (item) {
// 查找第一個(gè)符合大于3的下標(biāo)(找到了就停止)
// 返回3
return item > 3;
}));
}
{
// 數(shù)組中是不是包含了1
// true
console.log('number',[1,2,NaN].includes(1));
// true
console.log('number',[1,2,NaN].includes(NaN));
}
新增特性:參數(shù)默認(rèn)值、rest參數(shù)、擴(kuò)展運(yùn)算符、箭頭函數(shù)、this綁定、尾調(diào)用
{
function test(x,y = 'world') {
// 如果y沒有值,就采用默認(rèn)值為world;如果有值,用采用傳遞過來的參數(shù)
console.log('默認(rèn)值',x,y)
}
test('hello');
test('hello','hjy');
// 錯(cuò)誤寫法:
// function test(x,y = 'world',c)
// 正確寫法:
// function test(x,y = 'world',c='bb')
}
{
let x = 'test';
// 都是取kill
function test2(x,y=x) {
console.log("作用域:",x,y);
}
// 作用域: kill kill
test2('kill');
function test3(c,y=x) {
// 作用域: kill test
console.log("作用域:",c,y);
}
test3('kill');
}
{
// ...arg不確定傳入幾個(gè)參數(shù),轉(zhuǎn)成一個(gè)數(shù)組
function test4(...arg) {
for(let v of arg){
// rest 1
// rest 2
// rest 3
// rest 4
// rest a
console.log('rest',v);
}
}
test4(1,2,3,4,'a');
}
{
// 把數(shù)組轉(zhuǎn)成一個(gè)離散的值
console.log(...[1,2,4]); // 1 2 4
console.log('a',...[1,2,4]);// a 1 2 4
}
{
// 函數(shù)
// arrow函數(shù)名 v參數(shù) v*2返回值
let arrow = v => v*2;
let arrow2 = () => 5;
console.log('a',arrow(3)); // a 6
console.log('a',arrow2()); // a 5
}
{
// 尾調(diào)用(提升性能:函數(shù)地址嵌套)
function tail(x) {
console.log('tail',x);
}
function fx(x) {
return tail(x)
}
fx(123)
}
新增特性:簡(jiǎn)潔表示法、屬性表達(dá)式、擴(kuò)展運(yùn)算符、Object新增方法
{
// 簡(jiǎn)潔表達(dá)
let o = 1;
let k = 2;
let es5 = {
o:o,
k:k
};
let es6 = {
o,
k
};
console.log(es5,es6); // {o: 1, k: 2} {o: 1, k: 2}
// 對(duì)象里有方法
let es5_method = {
hello:function () {
console.log('hello');
}
};
let es6_method = {
hello(){
console.log('hello');
}
};
console.log(es5_method.hello(),es6_method.hello());// hello hello
}
{
// 屬性表達(dá)式
let a = 'b';
let es5_obj = {
a:'c'
};
// [a]是一個(gè)變量
let es6_obj = {
[a]:'c'
};
// {a: "c"} {b: "c"}
console.log(es5_obj,es6_obj)
}
{
// 新增API
// Object.is與三個(gè)等號(hào)相同 輸出:true true
console.log('判斷2個(gè)字符串是否相等', Object.is('abc','abc'), 'abc' === 'abc');
// 數(shù)組是引用類型,但是數(shù)組引用的是不同地址 輸出:false false
console.log('數(shù)組',Object.is([],[]), [] === []);
// 當(dāng)個(gè)對(duì)象合并成一個(gè)對(duì)象{a: "a", b: "b"}
console.log('拷貝', Object.assign({a:'a'}, {b:'b'}));
// 對(duì)數(shù)組進(jìn)行遍歷
let test = {k:123,o:456};
for(let [key,value] of Object.entries(test)){
console.log(key,value);
}
}
ES6新增加的類型
就是這種數(shù)據(jù)類型,提供一個(gè)獨(dú)一無二(保證唯一)的值
{
// 聲明
let a1 = Symbol();
let a2 = Symbol();
// false
console.log(a1 === a2);
// 'a3'是一個(gè)key值
let a3 = Symbol.for('a3');
let a4 = Symbol.for('a3');
// true
console.log(a3 === a4);
}
{
// 使用場(chǎng)景:兩個(gè)相同的名字,不想去改變
let a1 = Symbol.for('abc');
let obj = {
[a1]:'123',
'abc':'345',
'c':456
};
console.log(obj); // {abc: "345", c: 456, Symbol(abc): "123"}
// symbol的值取不到
for(let [key,value] of Object.entries(obj)){
// let of abc 345
// let of c 456
console.log('let of', key, value);
}
// 取到symbol的值
Object.getOwnPropertySymbols(obj).forEach(function (item) {
// 123
console.log(obj[item])
});
// 兩種參數(shù)的值都可以獲取到
Reflect.ownKeys(obj).forEach(function (item) {
// ownKeys abc 345
// ownKeys c 456
// ownKeys Symbol(abc) 123
console.log('ownKeys', item, obj[item]);
})
}
{
let list = new Set();
list.add(5);
list.add(7);
// 判斷長(zhǎng)度 輸出:2
console.log('size',list.size);
}
{
let arr = [1,2,3,4,5];
let list = new Set(arr);
// 5
console.log('size', list.size);
}
{
// 運(yùn)用場(chǎng)景:去重
let list = new Set();
list.add(1);
list.add(2);
// 重復(fù)元素,沒有添加成功
list.add(1);
// {1, 2}
console.log('list',list);
let arr = [1,2,3,1,2];
let list2 = new Set(arr);
// 輸出{1,2,3}
console.log('unique',list2);
}
{
let arr = ['add','delete','clear','has'];
let list = new Set(arr);
// 判斷l(xiāng)ist里面有沒有add這個(gè)值 輸出:true
console.log('has', list.has('add'));
// 刪除list
console.log('delete', list.delete('add'), list);
// 清空list
list.clear();
console.log('list',list);
}
{
let arr = ['add','delete','clear','has'];
let list = new Set(arr);
for(let key of list.keys()){
// keys add
// keys delete
// keys clear
// keys has
console.log('keys',key);
}
for(let value of list.values()){
// values add
// values delete
// values clear
// values has
console.log('values',value);
}
for(let value of list){
// values add
// values delete
// values clear
// values has
console.log('values',value);
}
for(let [key,value] of list.entries()){
// entries add add
// entries delete delete
// entries clear clear
// entries has has
console.log('entries',key,value)
}
list.forEach(function (item) {
// add
// delete
// clear
// has
console.log(item);
})
}
{
// 和set的數(shù)據(jù)類型不一樣,WeakSet只是能對(duì)象,不能是數(shù)值,例如boolean
// WeakSet對(duì)象這塊,弱引用(不會(huì)檢測(cè)對(duì)象在其他地方引用到,意味著不會(huì)跟垃圾回收機(jī)制掛鉤到,簡(jiǎn)單說:WeakSet是一個(gè)地址的引用)
// WeakSet沒有clean、沒有set、不能遍歷
let weakList = new WeakSet();
let arg = {};
weakList.add(arg);
// 報(bào)錯(cuò)
// weakList.add(2);
console.log('weakList',weakList);
}
{
let map = new Map();
let arr = ['123'];
map.set(arr,456);
console.log('map', map, map.get(arr)); // key是123 value是456
}
{
let map = new Map([['a',123],['b',456]]);
console.log('map args', map); // {"a" => 123, "b" => 456}
console.log('size', map.size); // 2
console.log('delete', map.delete('a'), map); // {"b" => 456}
console.log('clear', map.clear(), map); // {}
}
{
// 與set和weakSet是一樣的
let weakmap = new WeakMap();
}
涉及的數(shù)據(jù)結(jié)構(gòu)能使用map,不使用數(shù)組
數(shù)據(jù)的唯一性使用set
{
// map 和 array 數(shù)據(jù)結(jié)構(gòu)橫向?qū)Ρ龋涸鰟h改查
let map = new Map();
let array = [];
// 增
map.set('t',1);
array.push({t:1});
console.info('map-array-add',map,array);
// 查
let map_exist = map.has('t');// true
let array_exist = array.find(item=>item.t);// 遍歷數(shù)組,查看是否存在;如果存在,就返回值
console.info('map-array-find', map_exist, array_exist);
// 改(map比較簡(jiǎn)單,array復(fù)雜)
map.set('t',2);
array.forEach(item => item.t ? item.t = 2 : '');
console.info('map-array-modify',map, array);
// 刪(map比較簡(jiǎn)單,array復(fù)雜)
map.delete('t');
let index = array.findIndex(item => item.t);
array.splice(index,1);
console.info('map-array-remove',map, array);
}
{
// set 和 array 的對(duì)比
let set = new Set();
let array = [];
// 增
set.add({t:1});
array.push({t:1});
console.info('set-array-add', set, array);
// 查
let set_exist = set.has({t:1});// false
let array_exist = array.find(item=>item.t);// 遍歷數(shù)組,查看是否存在;如果存在,就返回值
console.info('set-array-find', set_exist, array_exist);
// 改
set.forEach(item => item.t ? item.t=2 :'');
array.forEach(item => item.t ? item.t=2 :'');
console.info('set-array-modify', set, array);
// 刪(set和array刪除都相對(duì)麻煩)
set.forEach(item => item.t ? set.delete(item) : '');
let index = array.findIndex(item => item.t);
array.splice(index, 1);
console.info('set-array-remove', set, array);
}
{
// set map 和 object 對(duì)比
let item = {t:1};
let map = new Map();
let set = new Set();
let obj = {};
// 增
map.set('t',1);
set.add(item);
obj['t'] = 1;
console.info('map-set-obj', obj, map, set);
// 查(obj不如map和set語義化)
console.info({
map_find:map.has('t'),
set_find:set.has(item),
obj_find:'t' in obj
});
// 改
map.set('t',2);
item.t = 2;
obj['t'] = 2;
console.log('map-set-obj-modify', obj, map, set);
// 刪(set和array刪除都相對(duì)麻煩)
map.delete('t');
set.delete(item);
delete obj['t'];
console.log('map-set-obj-remove', obj, map, set);
}
Proxy代理,代理商:用戶 和 商家(連接了用戶和最真實(shí)對(duì)象的一個(gè)層)
Reflect反射
{
// 供應(yīng)商 原始對(duì)象,存儲(chǔ)真實(shí)數(shù)據(jù)
let obj = {
time:'2017-03-11',
name:'net',
_r:123
};
// 代理商
let monitor = new Proxy(obj, {
// 攔截(代理)對(duì)象屬性的讀取
get(target, key){
// target相當(dāng)于obj
// console.log(target);
// 把2017替換成2018
return target[key].replace('2017','2018');
},
// 攔截對(duì)象設(shè)置屬性
set(target, key, value){
if(key === 'name'){
return target[key] = value
}else {
return target[key];
}
},
// 攔截key in object 操作
has(target, key){
if(key === 'name'){
return target[key]
}else{
return false;
}
},
// 攔截delete
deleteProperty(target,key){
if(key.indexOf('_') > -1){
delete target[key];
return true;
}else{
return target[key];
}
},
// 攔截Object.keys, Object.getOwnPropertySymbols, Object.getOwnPropertyNames
// 保護(hù)time的key不被用戶看到
ownKeys(target){
return Object.keys(target).filter(item=>item!='time')
}
});
console.log('get', monitor.time); // 2018-03-11
monitor.time = '2019';
monitor.name = 'hjy';
console.log('set',monitor.time); // 2018-03-11
console.log('set',monitor.name); // hjy
// time被攔截了 true false
console.log('has','name' in monitor, 'time' in monitor);
// 對(duì)象依舊存在
// delete monitor.time;
// console.log('delete', monitor);
// 成功的刪掉_r
// delete monitor._r;
// console.log('delete', monitor);
console.log('ownKeys',Object.keys(monitor));
}
{
let obj = {
time:'2017-03-11',
name:'net',
_r:123
};
// 讀取time的值
console.log('Reflect get', Reflect.get(obj,'time')); // 2017-03-11
// 把name改成hjy
Reflect.set(obj, 'name', 'hjy');
console.log(obj); // {time: "2017-03-11", name: "hjy", _r: 123}
// 判斷obj里是否有name
console.log('has',Reflect.has(obj,'name')); // true
}
{
function validator(target, validator) {
// 對(duì)target進(jìn)行代理
return new Proxy(target,{
// 保存配置選項(xiàng)
_validator:validator,
// 對(duì)set進(jìn)行修改
set(traget,key,value,proxy){
if(target.hasOwnProperty(key)){
let va = this._validator[key];
if(!!va(value)){
return Reflect.set(target,key,value,proxy);
}else{
throw Error(`不能設(shè)置${key}到${value}`)
}
}else{
throw Error(`${key} 不存在`)
}
}
})
}
const personValidators={
name(val){
return typeof val === 'string'
},
age(val){
return typeof val === 'number' && val > 18
}
};
class Person{
constructor(name,age){
this.name = name;
this.age = age;
return validator(this,personValidators)
}
}
const person = new Person('hjy',30);
console.log(person);
// 不能設(shè)置數(shù)字
// person.name = 48;
person.name = 'oli';
console.log(person);
}
類的概念:基本語法、類的繼承、靜態(tài)方法、靜態(tài)屬性、getter、setter
{
// 基本定義和生成實(shí)例
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
let v_parent = new Parent('v');
let v_parent2 = new Parent();
// {name: "v"}
console.log('構(gòu)造函數(shù)和實(shí)例',v_parent);
// {name: "hjy"}
console.log('構(gòu)造函數(shù)和實(shí)例',v_parent2);
}
{
// 繼承
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
class Child extends Parent{
}
// {name: "hjy"}
console.log('繼承', new Child());
}
{
// 繼承傳遞參數(shù)
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
}
class Child extends Parent{
constructor(name='child'){
// 修改父類的參數(shù)(要把super放在第一行)
super(name);
// 子類增加自己的屬性
this.type='childType';
}
}
// {name: "lio", type: "childType"}
console.log('子類向父類傳遞參數(shù)', new Child('lio'));
}
{
// getter setter
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
get longName(){
return '姓名:' + this.name
}
set longName(value){
this.name = value;
}
}
let v = new Parent();
// hjy
console.log('getter',v.longName);
v.longName='lio';
// lio
console.log('setter',v.longName);
}
{
// 靜態(tài)方法(通過類調(diào)用,而不是通過類的實(shí)例去調(diào)用)
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
// 靜態(tài)方法
static tell(){
console.log('tell');
}
}
// tell
Parent.tell();
}
{
// 靜態(tài)屬性
class Parent{
// 構(gòu)造函數(shù)
constructor(name='hjy'){
this.name = name;
}
// 靜態(tài)方法(不能定義靜態(tài)屬性)
static tell(){
console.log('tell');
}
}
// 靜態(tài)屬性
Parent.type = 'test';
// tell
console.log('靜態(tài)屬性',Parent.type);
}
異步編程的解決方法
A執(zhí)行完再執(zhí)行B,兩種實(shí)現(xiàn)方式:回調(diào)、事件觸發(fā)
{
// es5回調(diào)解決異步操作
let ajax = function (callback) {
console.log('執(zhí)行');
setTimeout(function () {
// 判斷回調(diào)是不是存在,如果存在,執(zhí)行下一步
callback && callback.call()
},1000)
};
ajax(function () {
console.log('timeout1');
});
}
{
// es6
let ajax = function () {
console.log('執(zhí)行2');
// 返回一個(gè)Promise實(shí)例(執(zhí)行下一步功能)
// resolve執(zhí)行下一步操作
// reject中斷下一步操作
return new Promise(function (resolve,reject) {
setTimeout(function () {
resolve();
},1000);
})
};
ajax().then(function () {
console.log('promise','timeout2');
})
}
{
// A執(zhí)行完再執(zhí)行B,B執(zhí)行完了執(zhí)行C ...
let ajax = function () {
console.log('執(zhí)行3');
// 返回一個(gè)Promise實(shí)例(執(zhí)行下一步功能)
// resolve執(zhí)行下一步操作
// reject中斷下一步操作
return new Promise(function (resolve,reject) {
setTimeout(function () {
resolve();
},1000);
})
};
ajax().then(function () {
return new Promise(function (resolve,reject) {
// 又可以下一步
resolve();
},2000)
}).then(function () {
console.log('timeout3');
})
}
{
// catch捕獲錯(cuò)誤
let ajax = function (num) {
console.log('執(zhí)行4');
return new Promise(function (resolve,reject) {
// 如果大于5,執(zhí)行下一步
if(num > 5){
resolve();
}else{
// 拋出錯(cuò)誤
throw new Error('出錯(cuò)了');
}
})
};
ajax(6).then(function () {
console.log('log',6);
}).catch(function (err) {
console.log('catch',err);
});
ajax(3).then(function () {
console.log('log',3);
}).catch(function (err) {
console.log('catch',err);
})
}
{
// 所有圖片加載完再添加到頁面
function loadImg(src) {
return new Promise((resolve,reject) => {
let img = document.createElement('img');
img.src = src;
// 圖片加載完
img.onload=function () {
resolve(img);
};
// 圖片加載失敗
img.onerror = function (err) {
reject(err);
};
})
}
function showImgs(imgs) {
imgs.forEach(function (img) {
document.body.appendChild(img);
})
}
// all:把多個(gè)Promise實(shí)例當(dāng)成一個(gè)Promise實(shí)例
Promise.all([
// 三張圖片都加載完,才會(huì)觸發(fā)all,才執(zhí)行then
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg')
]).then(showImgs)
}
{
// 有一個(gè)圖片加載完成添加到頁面
function loadImg(src) {
return new Promise((resolve,reject) => {
let img = document.createElement('img');
img.src = src;
// 圖片加載完
img.onload=function () {
resolve(img);
};
// 圖片加載失敗
img.onerror = function (err) {
reject(err);
};
})
}
function showImgs(img) {
let p = document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
// 三張圖片,只要有一個(gè)圖片加載出來,那個(gè)就先顯示在頁面上
Promise.race([
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg'),
loadImg('http://myoli.xin/public/images/banner.jpg')
]).then(showImgs)
}
操作數(shù)組、object、map、set
{
let arr = ['hello','world'];
let map = arr[Symbol.iterator]();
// {value: "hello", done: false}
console.log(map.next());
// {value: "world", done: false}
console.log(map.next());
// {value: undefined, done: true} true代表沒有下一步
console.log(map.next());
}
{
// 自定義iterator接口
// obj數(shù)據(jù)是我們自己填充
let obj = {
start:[1,3,2],
end:[7,9,8],
// Symbol.iterator變量名
[Symbol.iterator](){
let self = this;
// 記錄當(dāng)前遍歷索引
let index = 0;
// start和end合并成一個(gè)數(shù)組
let arr = self.start.concat(self.end);
// 記錄數(shù)組的長(zhǎng)度
let len = arr.length;
return {
next(){
if(index < len){
return {
value:arr[index++],
done:false
}
} else {
return {
value:arr[index++],
done:true
}
}
}
}
}
}
for(let key of obj){
console.log(key);
}
}
{
// 對(duì)數(shù)組進(jìn)行遍歷
let arr = ['hello','world'];
for(let value of arr){
// hello
// world
console.log('value',value);
}
}
異步編程的一種解決方案
{
// genertaor基本定義
// 與普通的函數(shù)不同:* 、 yield
let tell = function* () {
yield 'a';
yield 'b';
return 'c';
};
// 調(diào)用tell,執(zhí)行到第一個(gè)yield停止下來
let k = tell();
// 執(zhí)行第一個(gè)yield
// {value: "a", done: false}
console.log(k.next());
// 執(zhí)行第二個(gè)yield
// {value: "b", done: false}
console.log(k.next());
// 執(zhí)行retrun
// {value: "c", done: true}
console.log(k.next());
// {value: undefined, done: true}
console.log(k.next());
}
{
// of遍歷
let obj = {
};
obj[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
for(let value of obj){
// 1
// 2
// 3
console.log('value',value);
}
}
{
let state = function* () {
while(1){
yield 'A';
yield 'b';
yield 'c';
}
}
let status = state();
// {value: "A", done: false}
// {value: "b", done: false}
// {value: "c", done: false}
// {value: "A", done: false}
// {value: "b", done: false}
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
console.log(status.next());
}
{
// 抽獎(jiǎng)
let draw = function (count) {
// 具體抽獎(jiǎng)邏輯
console.info(`剩余${count}次`);
};
let residue = function* (count) {
while (count > 0){
count--;
yield draw(count);
}
};
// 可以抽獎(jiǎng)5次,如果是最后一次,點(diǎn)擊無效
let star = residue(5);
let btn = document.createElement('button');
btn.id = 'start';
btn.textContent = '抽獎(jiǎng)';
document.body.appendChild(btn);
document.getElementById('start').addEventListener('click',function () {
star.next();
},false)
}
{
// 長(zhǎng)輪詢(接口請(qǐng)求失敗,一直請(qǐng)求)
let ajax = function* () {
yield new Promise(function (resolve,reject) {
// 接口
setTimeout(function () {
resolve({code:0})
},200);
})
};
let pull = function () {
let genertaor = ajax();
let step = genertaor.next();
step.value.then(function (d) {
if(d.code != 0){
setTimeout(function () {
console.log('wait');
pull();
},1000);
}else{
console.log(d);
}
})
};
pull();
}
修飾器:是一個(gè)函數(shù),修改類的行為(擴(kuò)展類的動(dòng)能,只在類里修改有用)
{
// 是一個(gè)函數(shù)
let readonly = function (target, name, descriptor) {
descriptor.writable = false;
return descriptor
};
// 修改類的行為
class Test{
// 加了修飾器,就是不能重新修改參數(shù);只有只讀的狀態(tài)
// @readonly與上面的readonly要一致
@readonly
time(){
return '2017-03-11'
}
}
let test = new Test();
// 加了修飾器,就是不能重新修改參數(shù);只有只讀的狀態(tài)
// 報(bào)錯(cuò)
// test.time = function () {
// console.log('reset name')
// }
// 2017-03-11
console.log(test.time())
}
{
let typename = function (target,name,descriptor) {
// 靜態(tài)屬性
target.myname = 'hello';
};
// 修飾器(對(duì)類進(jìn)行修飾)
@typename
class Test{
}
console.log('類修飾符',Test.myname); // hello
// 第三方庫修飾器的js庫:core-decorators; npm install core-decorators
}
{
// 看廣告是show還是click
let log = (type) => {
return function (target,name,descriptor) {
let src_method = descriptor.value;
// 方法重新賦值
descriptor.value=(...arg)=>{
src_method.apply(target,arg);
console.info(`log ${type}`);
}
}
}
class AD{
@log('show')
show(){
console.info('ad is show');
}
@log('click')
click(){
console.info('ad is click');
}
}
// 實(shí)例化
let ad = new AD();
ad.show();
ad.click();
}
let A = 123;
let test = function () {
console.log('test');
}
class Hello{
test(){
console.log('class');
}
}
export default {
A,
test,
Hello
}
// 模塊化:導(dǎo)入所有 lesson只是一個(gè)別名
import * as lesson from './class/lesson18-module';
console.log(lesson.A);
console.log(lesson.test);
import Lesson18 from './class/lesson18-module';
console.log(Lesson18.A);