ES6 & TS

一句話概括ES6 和 JS 的關(guān)系

  • ES是標(biāo)準(zhǔn) JS是實(shí)現(xiàn)

ECMAScript 6.0(以下簡(jiǎn)稱 ES6)是 JavaScript 語(yǔ)言的下一代標(biāo)準(zhǔn)蝠检,已經(jīng)在 2015 年 6 月正式發(fā)布了谣殊。==它的目標(biāo)经窖,是使得 JavaScript 語(yǔ)言可以用來(lái)編寫復(fù)雜的大型應(yīng)用程序肠槽,成為企業(yè)級(jí)開發(fā)語(yǔ)言。==

  • 日常喊法隘庄,ES ≈ JS囤官。
  • ES6現(xiàn)在來(lái)說(shuō)泛指5.1版本后的Javascript標(biāo)準(zhǔn)。
  • 從2015年開始后颤霎,越來(lái)越多的瀏覽器開始支持ES6標(biāo)準(zhǔn)的媳谁,當(dāng)然即使如此它仍然不夠普及(用戶瀏覽器上跑的,程序員們的寫法友酱,大部分還是ES5標(biāo)準(zhǔn))晴音。

var 變成了 let定義變量 和 const定義常量

  • ES6以前:都用var
// var 和 function 存在變量提前聲明
// var 只會(huì)提前聲明 function既聲明又定義
console.log(a); // a=undifined
console.log(getA()); // '123'
var a = 1;
function getA() {
    return 123;
}
// var 和 function 定義的變量可以重復(fù)聲明重新賦值
var a = 1;
var a = 2;
function getA() {}
// 全局作用域下 var 和 function 定義的變量相當(dāng)于給全局對(duì)象window增加屬性window.變量名 = 值
console.log(window.a);
console.log("getA" in window);
  • let
// let 變量

// console.log(a); //報(bào)錯(cuò):a is not defined “a未被定義”
// 【1】let 定義的變量沒有提前聲明的特點(diǎn)
let a = 1;

// 【2】let 定義的變量無(wú)法像 var 一樣重復(fù)聲明
// let a = 2; //報(bào)錯(cuò):'a' has already been declared “a已經(jīng)被定義”

// 【3】let 定義的變量不會(huì)在全局對(duì)象window下生成新的屬性
console.log(window.a);

// 越來(lái)越嚴(yán)謹(jǐn)...
  • const
// const 常量

// 1、無(wú)法提前聲明 2缔杉、不可以重復(fù)聲明 3锤躁、全局作用域下不會(huì)給window對(duì)象增加屬性(ES6通用)
let a; //let 定義變量可以不給值 值默認(rèn)為undifined
console.log(a);
a = 1; //let 定義的變量不能重新定義重名變量 但可以重新賦值
console.log(a);

// const b; //會(huì)報(bào)錯(cuò):Missing initializer in const declaration “忘記給const定義的常量一個(gè)初始值”
// 【4】 const定義的常量一旦聲明必須賦值
const b = 1;

// 【5】const定義的常量一旦聲明將無(wú)法在程序運(yùn)行中重新賦值
// const b = 2; //會(huì)報(bào)錯(cuò):Identifier 'b' has already been declared “b已經(jīng)被定義了”
  • {塊級(jí)作用域}
// {塊級(jí)作用域} 
{
    let a = 1;
    console.log("第1作用域a=",a);;
    var b = 1;
}
console.log("b即使在塊級(jí)作用域中定義,依舊是全局的,b=",b);
{
    let a = 2;
    console.log("第2作用域a=",a);
    var b = 2;
}
console.log("b即使在塊級(jí)作用域中定義或详,依舊是全局的,同時(shí)依舊會(huì)給window增加屬性window.b",window.b);
console.log("塊級(jí)作用域下系羞,var和function聲明的變量依舊是全局的郭计。");
// console.log(a); // 報(bào)錯(cuò):a is not defined “a未定義” 在塊級(jí)作用域下a定義的變量只在作用域內(nèi)有效

/**
 * 實(shí)際應(yīng)用
 * 對(duì)象{} for(){} if(){}
 */

// ES6中,花括號(hào)想表示對(duì)象椒振,{}不可以放在行首昭伸。(ES6以為那是一個(gè)塊級(jí)作用域)
let obj = {name:"liuhaoyu",age:10};
({name:"liuhaoyu", age:10});
eval('var o = {name:"liuhaoyu", age:10}'); //eval將字符串轉(zhuǎn)成對(duì)象的時(shí)候也有這個(gè)問題

// if()
if(1) {
    var x = 1;
    let y = 1;
    function getX() {
        return x;
    }
}
// {里面用var} 下面的變量會(huì)提前聲明(即使if(false){} x依然等于undifined**但 function 不會(huì):function要if條件為true的時(shí)候,先給函數(shù)聲明賦值,再執(zhí)行if里面的代碼**) 
// {里面用var 和 function} 下面的變量會(huì)存在于全局作用域(下面兩個(gè)永遠(yuǎn)存在)
console.log(x);
// console.log(y); //y is not defined , if 里面 let 定義的變量 , 只在{里面跑,跑完出不來(lái)}
console.log(getX());

for(var i=0; i<5; i++) {
    console.log("現(xiàn)在i=",i);
}
console.log("for循環(huán)結(jié)束后,i=",i);

for(let j=0; j<5; j++) {
    console.log("現(xiàn)在j=",j);
}
// console.log("for循環(huán)結(jié)束后,j=",j); //j is not defined
console.log("let定義的變量j,for循環(huán)跑完就沒了");
  • 總結(jié):比以往更加嚴(yán)謹(jǐn),let聲明過的變量無(wú)法再重新聲明澎迎,let存在作用域的概念庐杨,最顯著的提升應(yīng)該是for循環(huán)那一部分,跑完就釋放了很好夹供。const在程序執(zhí)行時(shí)無(wú)法修改灵份。

解構(gòu)賦值

  • 什么是解構(gòu)賦值:等號(hào)左右兩邊結(jié)構(gòu)一樣(或按照一定規(guī)則類似)。左邊的變量逐一取值對(duì)應(yīng)右邊的每個(gè)元素或?qū)傩浴?/li>
  • 數(shù)組解構(gòu)
// 什么是解構(gòu)賦值,數(shù)組舉例:
// 先來(lái)個(gè)數(shù)組
let arr = [1, 2, 3];
// 現(xiàn)有變量 x,y,z想分別等于數(shù)組里的1,2,3
// ES5的寫法
// let x = arr[0];
// let y = arr[1];
// let z = arr[2];
// ES6提供的解構(gòu)賦值
let [x, y, z, l, m, n] = arr;
console.log("x=",x,",y=",y,",z=",z);
// 多出來(lái)的 = undifined
console.log("l=",l,",m=",m,",n=",n);

// 設(shè)默認(rèn)值 x2=10,只有后面解構(gòu)的值是undifined的時(shí)候,才會(huì)取默認(rèn)值
let [x1, x2=10] = [1, undefined];
let [y1, y2=10] = [1]; // 不寫就是undifined
console.log(x1, x2);
console.log(y1, y2);

// 省略賦值 想讓m1=1,m2=3:把中間空出來(lái)即可
let [m1, , m2] = [1, 2, 3];
console.log(m1,m2);

// 不定參數(shù)賦值 n1=1,n2=2,n3將會(huì)定于后面所有的元素組成的數(shù)組[3,4,5,6,7]...
let [n1, n2, ...n3] = [1,2,3,4,5,6,7]; // ...擴(kuò)展運(yùn)算符
console.log(n3);
  • 對(duì)象解構(gòu)
// 對(duì)象解構(gòu)賦值 要求變量名和屬性名是一致的(name=obj.name)
// let {name, age} = {name:'liuhaoyu', age:10};
// console.log(name);

// 設(shè)默認(rèn)值
let {name, age=100} = {name:'liuhaoyu'};
console.log(age);

// 先定義再賦值
let x1,x2;
// {x1, x2} = {x1:1, x2:2}; //塊作用域的問題
({x1, x2} = {x1:1, x2:2}); //這么寫就好了 {}不再行首即可
  • 數(shù)組對(duì)象嵌套解構(gòu)(只要左邊結(jié)構(gòu)和右邊一樣即可)
let obj = {
    name: 'liuhaoyu',
    age: undefined,
    // 嵌套個(gè)數(shù)組
    array: [
        'a1',
        'a2',
        'a3',
        'a4',
        // 數(shù)組里嵌套個(gè)對(duì)象
        {
            o1: 'o1',
            o2: 'o2',
            o3: 'o3'
        }
    ],
}

// 如何解構(gòu):照著結(jié)構(gòu)寫就行了,注意數(shù)組后面有個(gè):
let {name, age, array:[a1,a2,a3,a4,{o1, o2,o3}]} = obj;
console.log(name,age,a1,o1);
  • 數(shù)據(jù)類型不對(duì)應(yīng)的結(jié)構(gòu)
// 使用數(shù)組解構(gòu)字符串:會(huì)將右邊字符串轉(zhuǎn)換為數(shù)組
let [x, y] = "123";
// let [m, n] = 1; //會(huì)報(bào)錯(cuò):1 is not iterable 要求必須右邊是一個(gè)有l(wèi)ength屬性的東西(類數(shù)組:比如dom操作獲取一組元素,普通數(shù)組,Set對(duì)象,Map等)
console.log(x,y);

// 使用對(duì)象解構(gòu) : 如果右邊不是對(duì)象,會(huì)轉(zhuǎn)為對(duì)象,再進(jìn)行解構(gòu)賦值
// let {__proto__:a} = 1; 這句話的意思是,將 1這個(gè)對(duì)象中的proto屬性用變量a接收.
let {__proto__:a} = 1;
console.log(Object(1)); //看看1轉(zhuǎn)為對(duì)象是什么樣子
console.log(a); // undefined

let {length:objLen} = "1234";
console.log(objLen); 
  • 在參數(shù)列表里解構(gòu)
// 在參數(shù)列表中解構(gòu)數(shù)組
// 要求a等于數(shù)組第一個(gè)元素,b等于數(shù)組第二個(gè)元素,c等于剩下所有元素組成的數(shù)組
function getA([a,b,...c]) {
    console.log(a);
    console.log(b);
    console.log(c);
}
let arr = [1,2,3,4,5,6,7,8,9];
getA(arr);

// 在參數(shù)列表中解構(gòu)對(duì)象 還能給默認(rèn)值
function getO({name, age=100}) {
    console.log(name);
    console.log(age);
}
let obj = {name:'liuhaoyu', age:undefined};
getO(obj);

// 在參數(shù)列表中解構(gòu)對(duì)象 給默認(rèn)值,要求不傳任何參數(shù)不報(bào)錯(cuò)依然可以打印name和age
function getObj1({name='liuhaoyu', age='100'} = {}) {
    console.log(name);
    console.log(age);
}
// 看看這種寫法
function getObj2({name, age} = {name:'liuhaoyu', age:100});
getObj1(); 
getObj2(); //不寫都一樣
getObj1({}); // 傳了一個(gè)空對(duì)象.默認(rèn)值為空對(duì)象,沒問題
getObj2({}); // 傳了一個(gè)空對(duì)象,默認(rèn)值為{name:'liuhaoyu', age:100},現(xiàn)在值為{},所以會(huì)出現(xiàn)name,age = undefined

字符串方法擴(kuò)展

// 看看字符串原型有哪些方法和屬性
// console.log(String.prototype);

let str = "abcdefg12345";

// 1 includes("指定字符串string", 開始查找的位置int默認(rèn)0) 返回 true|false
console.log(str.includes('cdef', 3));

// 2 startsWiths("指定字符串string", "開始查找的位置int默認(rèn)0") | endsWith, 判斷字符串是否以指定字符 開頭 | 結(jié)尾
console.log(str.startsWith('bcd', 1));
console.log(str.endsWith('345',3)); //endsWith第二個(gè)參數(shù)是判斷:前幾個(gè)字符組成的字符串是否以第一個(gè)參數(shù)結(jié)尾

// 3 repeat(重復(fù)多少次)
console.log(str.repeat(3));

// 4 ES7新增 : padStart(最終長(zhǎng)度int, "指定字符string") padEnd 按照指定字符,補(bǔ)全字符串的長(zhǎng)度
let str1 = 'ab';
console.log(str1.padStart(5,"cde")); //補(bǔ)在前面
console.log(str1.padEnd(3,"cde"));  //補(bǔ)在后面 , 長(zhǎng)度超了自動(dòng)截取 

==模板字符串==

// `` 包起來(lái),跟普通字符串一樣
let str = `哈哈`;
// 但是可以添加變量 ${}
let strMid = 'ha';
str = `哈 ${strMid} 哈`;
console.log(str);

// 實(shí)際應(yīng)用: js動(dòng)態(tài)渲染網(wǎng)頁(yè)
var content = "我是要被渲染進(jìn)去的內(nèi)容";
// ES5中
var htmlText = 
    '<div>' +
        '<span>' + content + '</span>';
    '</div>';
// 插入 $("body").innerHTML(htmlText);

// ES6中
let htmlText1 = `
    <div>
        <span> ${content} </span>
    </div>
`; 

數(shù)組方法擴(kuò)展

/**
 * 數(shù)組的空位 : 數(shù)組某個(gè)索引位置沒有任何值empty *undefined不是空位*
 */
let arr = [,undefined,,,]; //一個(gè) , 一個(gè)空位
console.log(arr.length);
// in: 判斷數(shù)組索引位置上有沒有值 undefined不是空位 返回值為true
console.log(1 in arr);

// 在ES5中 數(shù)組方法對(duì)空位的處理不一致 一般直接跳過空位
let arr1 = [1,2,,,,3];
arr1.filter(function(item) { // filter是ES5的方法
    console.log(item); //跳過空位
});

// 在ES6中 將空位處理為undefined 
arr1.find(function(item) {
    console.log(item);
});
for(let item of arr1) {
    console.log(item);
}

// 面試題 得到一個(gè)有7個(gè)1的數(shù)組
console.log(Array(7).fill(1));

對(duì)象擴(kuò)展

  • 更簡(jiǎn)潔的表達(dá)方式
let name = "liuhaoyu", age = 100;
let person = {name, age};
// let person = {name:name, age:age};
let str = 'name';
let obj = {
    fn(){},
    // fn:function(){}
    // 屬性名是字符串
    str: name, //這個(gè)是把name 賦值給了 obj.str
    // [變量]: 值, //這樣可以把變量的值當(dāng)作屬性名key.
    [str]: name, //這個(gè)是把name 賦值給了 obj.name
    ["my"+str]: name, //還可以拼接
}
console.log(obj.name);
  • set和get
// 普通set
// obj.name = 'liuhaoyu';
// 普通get
// obj.name
let obj = {
    get name() {
        // 這個(gè)函數(shù)只要調(diào)用 obj.name時(shí) 就會(huì)觸發(fā)
        // 可以通過return 返回值
        return 'liuhaoyu';
    },
    // 必須有1個(gè)參數(shù)
    // set name(value) {
        // this.name = value;
        // 不能這么寫,會(huì)一直調(diào)用自己
    // }
}
console.log(obj.name);
  • 對(duì)象的擴(kuò)展方法
// Object(); //將參數(shù)變成對(duì)象
// console.log(Object(1));

// is 判斷兩個(gè)值是否相等
// ES5 "===" 判斷的問題 : NaN !== NaN (NaN和任何值都不等) | -0 === 0 (-0和0又相等)
console.log((NaN === NaN)); //false
console.log((-0 === 0)); //true
// 用Object.js判斷
console.log(Object.is(NaN, NaN)); //true
console.log(Object.is(-0, 0)); //false

// assign 合并對(duì)象
let obj1 = {name:'liuhaoyu'};
let obj2 = {age:10};
Object.assign(obj1, obj2); //將第個(gè)對(duì)象的所有屬性 合并到第一個(gè)對(duì)象
console.log(obj1); //第一個(gè)會(huì)變
console.log(obj2); //第二個(gè)不變
obj1 = {name:'liu'};
obj2 = {name:'liuhaoyu', age:20};
Object.assign(obj1, obj2);
console.log(obj1); //如果兩個(gè)屬性名稱重復(fù) 那么第二個(gè)會(huì)覆蓋第一個(gè)的值
console.log(obj2);

// ES7中提供的 對(duì)象的擴(kuò)展運(yùn)算符 ... 合并對(duì)象
let o1 = {name:'liu'};
let o2 = {name:'hao'};
let me = {...o1, ...o2}; // 這樣合并為一個(gè)新對(duì)象,原對(duì)象o1 o2不變
console.log(o1);
console.log(o2);
console.log(me);

// getOwnPropertyDescriptor 獲取一個(gè)對(duì)象中的某個(gè)屬性的描述
let desc = Object.getOwnPropertyDescriptor("123", length); // 獲取對(duì)字符串對(duì)象的 length的描述
console.log(desc);
// 具體打印的屬性
// configurable: false #不可配置 (是否可以刪除這個(gè)屬性)
// enumerable: true #可枚舉
// value: "1" #具體值
// writable: false #不可修改

// keys() 返回值 數(shù)組 [所有可枚舉的屬性]
console.log(Object.keys(me));

// values() 返回值 數(shù)組 [所有可枚舉屬性的鍵值]
console.log(Object.values(me));

// entries() 返回值 數(shù)組 [[鍵], [值]]
console.log(Object.entries(me));
  • proxy
let user = {}; // 有一個(gè)人
user.fname = 'Horry'; //名hoory
user.lname = 'yoo'; //姓yoo
// user.name = user.fname + '.' + user.lname; //他的全名就是Horry.Yoo
console.log(user.name);
// 每次算name很麻煩
user = {
    fname: 'Horry',
    lname: 'Yoo',
    name: function() {
        return this.fname + '.' + this.lname;
    }
};
// 想要獲得全名name()
console.log(user.name());
// 這個(gè)()看著很刺眼,我希望全名是個(gè)屬性而不是個(gè)方法
let newUser = new Proxy({}, {
    get: function(obj, prop) {
        if(prop === 'name') {
            return obj.fname + '.' + obj.lname;
        }
    }
});
/**
 * new Proxy({原對(duì)象}, {
 *  // 代理對(duì)象
 *  get: function(obj表示原對(duì)象, prop表示叫的屬性名) {
 *   // 判斷prop的值 返回叫的指定屬性的值
 *  }
 * })
 */
newUser.fname = 'haoyu';
newUser.lname = 'Liu';
console.log(newUser.name);

新的數(shù)據(jù)類型和對(duì)象

  • Symbol
/**
 * Symbol 是ES6新增的一個(gè)基本數(shù)據(jù)類型
 */
// 定義 Symbol() 
let sym1 = Symbol();
let sym2 = Symbol();
console.log(typeof(sym1));
console.log(typeof(sym2));
console.log(sym1 === sym2); // 不全等
// Symbol數(shù)據(jù)類型的特點(diǎn) : 跟字符串差不多 但是使用Symbol()函數(shù)得到一個(gè)數(shù)據(jù) 每一個(gè)都是完全不同的
// 可以接收一個(gè)參數(shù)('描述這個(gè)Symbol')
// 即使描述一樣 值也是不一樣的
sym1 = Symbol('foo');
sym2 = Symbol('foo');
console.log(sym1);
console.log(sym2);

// 具體作用: 作對(duì)象屬性的名稱,防止對(duì)象屬性被重寫
let person = {
    name: 'haoyu',
}
person.name  = 'horry'; //加入我們引用了一個(gè)person對(duì)象,但不知道person里有name屬性,我們大膽地把它改了
//這樣做很危險(xiǎn),可能有其他的代碼依賴這person.name這個(gè)屬性,我們把它改了可能直接導(dǎo)致整個(gè)程序崩掉
console.log(person);
// ES6中解決它:
let name = Symbol('name');
person = {
    [name] : 'haoyu',
}
person.name = 'horry';
console.log(person);
// 再看個(gè)例子
// file1.js
let p;
{
    let n = Symbol('name');
    p = {
        [n] : 'file1',
    };
}
// file2.js
{   
    let n = Symbol('name');
    p[n] = 'file2';
}
console.log(p);
// 你會(huì)發(fā)現(xiàn)p對(duì)象里有兩個(gè)
// Symbol(name): "file1"
// Symbol(name): "file2"
// 即在不同的作用域, Symbol的值無(wú)法改變
  • Set
/**
 * Set 
 * 可以理解為一個(gè)元素的值絕對(duì)不會(huì)重復(fù)的強(qiáng)數(shù)據(jù)類型數(shù)組
 */

// 先來(lái)個(gè)數(shù)組
let arr = [1, 2, 3, 3]; //可以寫2個(gè)3
// 定義set : new Set(傳個(gè)數(shù)組進(jìn)來(lái))
let set = new Set(arr); 
console.log(set); //你會(huì)發(fā)現(xiàn)3只出現(xiàn)了一次
set = new Set([1,'1', 2, '2', 3, '3']);
console.log(set); //在set里 1!='1' 即值沒有重復(fù)

// Set的一些常用屬性和方法
// Set.size ≈ Array.length
console.log('size中共有元素:', set.size);

// 添加和刪除 元素
set.add(4); //添加元素
set.add(4); //添加元素
// 添加兩次也不會(huì)報(bào)錯(cuò),只是依然只有一個(gè)數(shù)字4存在Set中
set.delete('2'); //刪除元素
set.delete('2'); //刪除元素
// 刪除同理,刪了再刪,不會(huì)報(bào)錯(cuò)

// 看看有沒有某個(gè)元素 有true 沒有false
console.log(set.has(5));

// 清空Set
set.clear();
console.log(set);
  • Map
// 創(chuàng)建一個(gè)Map
// new Map([[key, value], [key, value], [key, value]]); 
// 參數(shù)要求 傳進(jìn)來(lái)的是一個(gè)二維數(shù)組 一維數(shù)組必須是[第一個(gè)元素當(dāng)key, 第二個(gè)元素當(dāng)value];
let map1 = new Map([[1,'liu'], [2, 'hao'], [3, 'yu']]);
console.log(map1);
// 一個(gè)對(duì)象 屬性名必須是字符串,如果你寫的不是字符串也默認(rèn)轉(zhuǎn)換為字符

let o = {};
let a = [];
let obj = {
    true: 'true', //前面的true 就不是關(guān)鍵字"真"了 而是可以通過obj.true調(diào)用的一個(gè)屬性的屬性名
    1: 1, //同理前面的1也不是常量1,而是obj中的一個(gè)屬性的屬性名
    [a]: [],
    [o]: {}, // 即使我們?cè)趯?duì)象外面去定義變量然后用[變量名]這樣的方式創(chuàng)建對(duì)象的屬性,屬性名依然會(huì)是一個(gè)字符串
}
// console.log(obj); //也就是說(shuō)無(wú)論如何, 屬性名一定是個(gè)字符串

// Map解決了這樣一個(gè)問題: 屬性名(key)可以是任意數(shù)據(jù)類型
let map2 = new Map([['name','liuhaoyu'], [true, 'true'], [{age:12}, {age:12}], [[1,2,3], [1,2,3]]]);
console.log(map2); //上面的Map , 四個(gè)鍵值對(duì)的key 分別是 字符串, 布爾, 對(duì)象, 數(shù)組
// 當(dāng)然對(duì)象和數(shù)組這種可以給它一個(gè)第一參數(shù)[暫時(shí)叫做代號(hào)吧, key, value]
map2 = new Map([['name','liuhaoyu'], [true, 'true'], [o, {age:12}, {age:12}], [a, [1,2,3], [1,2,3]]]);

// Map常用的屬性和方法
// size 鍵值對(duì)的個(gè)數(shù)
console.log(map2.size);

// get 通過key或代號(hào)獲取value
console.log(map2.get('name'));
console.log(map2.get(true));
console.log(map2.get(o));
console.log(map2.get(a));

// set 通過key或代號(hào)新增或修改value
map2.set('age', 20); //沒有age 新增age
map2.set('name','horryyoo'); //有name 修改name
console.log(map2);

// has 通過key判斷有沒有對(duì)應(yīng)的value值
console.log(map2.has('age'));

// delete 通過key或代號(hào)干掉一個(gè)屬性 找到元素并刪除成功為true 找不到或刪不掉為false
console.log(map2.delete('age'));
console.log(map2);

// 清空 沒有返回值
// map2.clear();
// console.log(map2.size);

// 遍歷forEach(順序必須是 參數(shù)1是值, 參數(shù)2是鍵, 參數(shù)3是實(shí)例)
map2.forEach((value, key, instance)=> {
    console.log(value); //value
    console.log(key); //key
    console.log(instance); //實(shí)例
});

// for of + Map.keys() 遍歷所有的key
for (let key of map2.keys()) {
    console.log(key);
}

// for of + Map.values() 遍歷所有的value
for (let value of map2.values()) {
    console.log(value);
}

// 練習(xí):給你一個(gè)數(shù)組變成Map實(shí)例
let ary = ['liuhaoyu', 'JS', 'ES6', 'AngularJS2+', 'Laravel'];
let map3 = new Map();
for (let [index, item] of ary.entries()) {
    map3.set(index, item);
}
console.log(map3);

oop => 類的擴(kuò)展

class關(guān)鍵字 和constructor()構(gòu)造函數(shù)

// ES5 通常是這樣弄個(gè)對(duì)象出來(lái)的
// 類定義
function Fn() {
    this.x = 10;
}
// 實(shí)例化
var f = new Fn();

// ES6 有 class 了
class A {
    // 同時(shí)有構(gòu)造函數(shù)了
    constructor(x, y) {
        this.x = x; // 添加私有屬性
        this.y = y;
    }
}
let a = new A(1,2);
console.log(a);

類的“立即執(zhí)行” 和 變量提前聲明

// 立即執(zhí)行 let 變量 = new class {構(gòu)造函數(shù)(){}}("傳入?yún)?shù)立即執(zhí)行");
let aa = new class {
    constructor(name) {
        this.name = "name";
    }
}("liuhaoyu");
console.log(aa);

// ES5 老方法定義類和實(shí)例化時(shí)哮洽,變量會(huì)提前聲明
let ff = new FF();
console.log(ff);
function FF() {
    this.f = "ff";
}
// ES6
// let c = new C(); //ES6中沒有變量提聲:這里會(huì)報(bào)錯(cuò)找不到C
class C {
    constructor() {
        this.c = 'c';
    }
}
let c = new C(); //ES必須寫在后面

繼承 extends

class A {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    fn1() {
        console.log('我是A.fn1()');
    }
    static fn2() {
        console.log('我是A.fn2()');
    }
}

// 繼承extends
class B extends A {
    constructor(x, y) {
        // this.y = y; // 報(bào)錯(cuò) ust call super constructor in derived class before accessing 'this' or returning from derived constructor
        // console.log(this); // 子類沒有 "this" 它的this是父類填渠,因此需要調(diào)用super()方法
        super(x, y);
        // 在super()執(zhí)行完成后,就可以使用this了
        alert(this.y);
    }
    // 當(dāng)然 子類的constructor()構(gòu)造函數(shù)是可以省略的鸟辅,它會(huì)自動(dòng)繼承父類的constructor()方法
    // 所以上面所有代碼都在“脫了褲子放屁”
    // 方法可以重寫
    fn1() {
        console.log('我是B.fn1()');
    }
    static fn2() {
        console.log('我是B.fn2()');
    }
}
let b = new B(1,2);
b.fn1();
A.fn2();
B.fn2();
console.log(b);

靜態(tài)方法

// static 定義靜態(tài)方法 (比如Array.of) 
class AA {
    static myStaticFn() {
        alert('這是一個(gè)靜態(tài)方法揭蜒,只有類本身才能調(diào)用。');
    }
}
AA.myStaticFn();

// 靜態(tài)方法無(wú)法被實(shí)例拿到
// let aa = new AA();
// aa.myStaticFn(); // 報(bào)錯(cuò) aa.myStaticFn is not a function “對(duì)象是繼承不到靜態(tài)方法的”

// 靜態(tài)方法也無(wú)法被繼承
class B1 {
    static myStaticFn() {
        console.log('我是b1的靜態(tài)方法');
    }
}
class B2 extends B1 {}
// console.log(B2.myStaticFn()); //undefined
// 但是我非要拿到B1的靜態(tài)方法怎么辦呢剔桨?
class B3 extends B1 {
    // 1、再定義一個(gè)靜態(tài)方法
    static myStaticFn2() {
        // 2徙融、這個(gè)方法執(zhí)行調(diào)用 super這里相當(dāng)于父類B1.myStaticFn()父類的靜態(tài)方法
        super.myStaticFn();
    }
}
// let b3 = new B3();
// console.log(b3.myStaticFn2());

函數(shù)方面的擴(kuò)展

  • ==默認(rèn)值問題==
/**
 * 參數(shù)默認(rèn)值問題
 */
// function fn(x,y) {
//     // ES5我們這樣設(shè)置默認(rèn)值 如果 x為真 函數(shù)內(nèi)的x = x 否則 = 我們?cè)O(shè)置的默認(rèn)值'liuhaoyu'
//     x = x || 'liuhaoyu';
//     y = y || 'ES6';
// }
// // 問題來(lái)了
// fn(0,0);    //這樣傳進(jìn)去 0被讀成false 則函數(shù)內(nèi)x = 'liuhaoyu'
// ES6支持參數(shù)列表中設(shè)置默認(rèn)值
function fn(x='liuhaoyu', y='ES6'){};
// ES6參數(shù)列表還支持解構(gòu)賦值
function fn1({name="liuhaoyu", age="100"}={}) {
    console.log(name);
    console.log(age);
}
fn1();

/**
 * function.length 屬性 沒有默認(rèn)值的形參的個(gè)數(shù)
 */
function fn2(x, y) {

}
fn2(1,2);
console.log(fn2.length);

/**
 * 參數(shù)默認(rèn)值位置
 * 一般參數(shù)的默認(rèn)值都放在最后面
 */
// function fn3(x=10, y=20) {}

// arguments 類數(shù)組 實(shí)參集合
function fn4(...arg) {
    // ES5 獲取實(shí)參 集合
    console.log(arguments); //對(duì)象
    // ES6 獲取實(shí)參集合 參數(shù)列表中解構(gòu)取值
    console.log(arg); // 數(shù)組
}
fn4(1,2,3,4,5);

// 參數(shù)作用域
let x = 100;
function fn5(x, y=x) {
    console.log(y); //為什么y=1 而!= 100呢
}
fn5(1);
/**
 * 解釋: 參數(shù)列表作用域是這么找值的
 * x=1 進(jìn)來(lái)了 y=x 這里的這個(gè)x是先找函數(shù)里面的x,沒有,才會(huì)找函數(shù)外面的x(上面的x=100)
 */
  • 函數(shù)名問題
function fn() {

}

// 獲取當(dāng)前函數(shù)名
console.log(fn.name);
// 匿名函數(shù)名
console.log((function(){}).name);

// 特殊情況
// 1. 通過bind方法得到一個(gè)新的函數(shù) name是 "bound 原來(lái)函數(shù)名字"
let fn1 = fn.bind(null);
console.log(fn1.name);
// 2. 通過構(gòu)造函數(shù)創(chuàng)建一個(gè)函數(shù) new Function("形參", "函數(shù)體") name 是 "anonymous" 即匿名
let fn2 = new Function("x,y", "console.log(x,y); return x+y;");
console.log(fn2(10,100));
console.log(fn2.name); 

// 面試題 禁止使用eval() 使用new Function的方法 取得str 的json字符串
let str = '[{"name": "珠峰"}, {"age":100}]';
let arr = (new Function("return" + str))();
// console.log(arr);
// arr ==> [{"name": "珠峰"}, {"age":100}]
  • 擴(kuò)展運(yùn)算符:更多的是操作數(shù)組
/**
 * 擴(kuò)展運(yùn)算符 ...
 */
// 將非數(shù)組變成數(shù)組(類數(shù)組 length) [...]
let str = "123";
console.log([...str]);
function fn(str) {
    console.log([...arguments]);
}
fn(str);

// 將數(shù)組變成非數(shù)組
let arr1 = [1,2,3,4];
let arr2 = [10,20,30,40];
// 合并他們
newArr1 = arr1.concat(arr2); //可以用Array.concat()函數(shù)
newArr2 = [...arr1,...arr2]; //也可以使用擴(kuò)展運(yùn)算符把他們連起來(lái)
console.log(newArr1);
console.log(newArr2);

/**
 * 實(shí)際應(yīng)用
 */
// 求數(shù)組最大值
let ary = [1,23,12,45,242,132];
// Math.max(ary); //×
// Math.max.apply(null, ary); //√
let max = Math.max(...ary); //把數(shù)組展開
console.log(max);

// 把數(shù)組展開傳進(jìn)參數(shù)列表
function fn1(...ary) {

}

  • 箭頭函數(shù)
function fn(x, y) {

}
// 箭頭函數(shù)都是匿名函數(shù)
// let 函數(shù)名 = (參數(shù)列表) => {函數(shù)體}
let fn1 = () => {};
// 參數(shù)列表只有一個(gè)參數(shù) 函數(shù)體只有一段代碼 可以省略參數(shù)列表 函數(shù)體可以省略{} 和 return
let fn2 = x => x+1;
// 通常函數(shù)當(dāng)作參數(shù)的時(shí)候使用箭頭函數(shù)
let ary = ['liu', 1, 2, 3, 'haoyu'];
let newAry = ary.filter(item => typeof item === "number");
console.log(newAry);

/**
 * 特點(diǎn)
 */
// 1. 箭頭函數(shù)沒有this指向 里面的this是上一級(jí)的作用域
let obj = {
    fn: function() {
        let f=()=> { 
            console.log(this); // 這里的this得是上一級(jí)
        }
        f();
    },
}
obj.fn();

// 2. 箭頭函數(shù)沒有arguments
let f1 = () => {
    console.log(arguments);
}
// f1(123);
// 我非要拿到實(shí)參集合
let f2 = (...arg) => {
    console.log(arg);
}
f2(1,2,3);

// 3. 箭頭函數(shù)不可以用作構(gòu)造函數(shù) 因?yàn)椴豢梢允褂胣ew 執(zhí)行
function FF () {
}
console.log(new FF);

let F=()=>{};
console.log(new F); // F is not a constructor
  • async 異步函數(shù)
console.log("這是同步代碼開始1");

// 2
async function fn() {
    return "執(zhí)行fn()方法成功2";
}
console.log("這是定義了一個(gè)一步方法fn()3");

fn().then(function(res){
    console.log(res);
}).catch(function(e) {
    console.log(e);
});
console.log("我已經(jīng)調(diào)用了方法fn()洒缀,并且給他“綁定”了then()執(zhí)行成功回調(diào)和catch()執(zhí)行錯(cuò)誤回調(diào)4");

/**
 * 執(zhí)行順序:1 3 4 2
 * 原因:我們定義的是一個(gè)非阻塞的異步方法 anync function () {}
 * 好處:異步執(zhí)行:程序跑到2的時(shí)候,開個(gè)任務(wù)欺冀,繼續(xù)往下執(zhí)行树绩,最后跑回去執(zhí)行2。(類似node.js)
 * 調(diào)用方法: 1調(diào)用函數(shù)fn().2調(diào)用then(res) {//這里的res就是fn()執(zhí)行完成后return回來(lái)的結(jié)果}.3調(diào)用catch(e) {//這里的e就是錯(cuò)誤信息}
 */

ES 的 “模塊化”

  • 定義模塊 和 暴露模塊 ==e.js==
// 定義
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

// 暴露
export {firstName, lastName, year};
  • 引用模塊 和 使用它內(nèi)部的元素(變量隐轩、函數(shù)等) ==i.js==
// 引用
// 全部引用
// import * as mj from './e';
// 調(diào)用
// console.log(mj.firstName);
// 解構(gòu)引用
import {firstName, lastName} from './e';
console.log(firstName);
  • 在html文檔中調(diào)用模塊化的js文件時(shí)
<!-- 寫上type="module" -->
<script type="module" src="./modules/i.js"></script>

TS

  • 大白話:改進(jìn)了JS饺饭。
  • ES6語(yǔ)法寫,可以編譯為支持ES5及以下的版本职车。

開發(fā)環(huán)境搭建

  • npm安裝typescript
# 先裝cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 再用cnpm 裝 typescript
cnpm install -g typescript
  • 編譯 tsc 命令編譯 .ts 文件
tsc name.ts

會(huì)生成一個(gè)編譯后可以放在瀏覽器里執(zhí)行的.js文件

多行字符串

  • 這個(gè)好像是ES6提供的吧【``】
# ES5-
var htmlText = "aaa" +
    "bbb" + 
    "ccc"; //無(wú)法換行 換行需要用+連接

# ES6 / TS
var htmlText = `aaa
bbb
ccc
`;

模板字符串

var htmlText = `
<div>
 <span> ${變量|方法()} </span>
</div>
`

自動(dòng)拆分字符串

// 定義一個(gè)方法
function test(template, name, age) {
    console.log(template);
    console.log(name);
    console.log(age);
}

// 定義參數(shù)
var myName = 'liuhaoyu';
var getAge = function() {
    return 500;
}

// 調(diào)用方法 test`整個(gè)對(duì)應(yīng)參數(shù)template,  ${myName}對(duì)應(yīng)參數(shù)name, ${myAge}對(duì)應(yīng)參數(shù)age`
test`hellow my name is ${myName}, I'm ${ageAge()}`

函數(shù)默認(rèn)參數(shù)

/**
 * 默認(rèn)參數(shù)值
 */
// 調(diào)用test()時(shí)瘫俊,我如果只寫兩個(gè)參數(shù),那么c默認(rèn)值'liuhaoyu' 
// 有默認(rèn)值的參數(shù)最好寫在最后面
function test(a:string, b:string, c:string='liuhaoyu') {
    console.log(a);
    console.log(b);
    console.log(c);
}

test('a', 'b');

==函數(shù)可選參數(shù)==

/**
 * 可選參數(shù)
 */
// 聲明可選參數(shù) b?
// 可選參數(shù)必須寫在必選參數(shù)后面
// 順序: (必選參數(shù)悴灵, 可選參數(shù)扛芽?, 帶默認(rèn)值的參數(shù)=默認(rèn)值)
function test(a:string, b?:string, c:string='liuhaoyu') {
    // 如果你聲明了可選參數(shù)积瞒,在有必要的情況下川尖,請(qǐng)?jiān)诤瘮?shù)內(nèi)部處理當(dāng)可選參數(shù)沒填時(shí)候的情況
}

test('hahaha');

解構(gòu)賦值(ES6)

function getStock() {
    return {
        code: 'ibm',
        price: 100,
    }
}
// 跟ES6解構(gòu)賦值一樣
var {code, price} = getStock();

箭頭函數(shù)(ES6)

// 箭頭函數(shù): (參數(shù)列表)=>{函數(shù)體}
// var fn = () => {};

// 箭頭函數(shù)好處
// ES5-
function getStock(name) {
    this.name = name;
    setInterval(function() {
        console.log('name is', this.name);
    }, 1000);
}
var stock = new getStock("IBM"); // 無(wú)法讀得到this.name

// ES6 TS:
function getStock2(name:string) {
    this.name = name;
    // 不僅代碼更少,而且this關(guān)鍵字可用
    setInterval(()=>{
        console.log('name is', this.name);
    }, 1000);
}
var stock = new getStock2("IBM2"); //可以讀取this.name = ibm2

擴(kuò)展操作符... (ES6)

// 無(wú)限參數(shù)列表的函數(shù)
function fn1(...args) {
    // 傳進(jìn)去的其實(shí)是一個(gè)數(shù)組
    // 原理是編譯后js遍歷Function.arguments屬性
    args.forEach(function(arg) {
        console.log(arg);
    })
}

function fn2(a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
}
// 傳實(shí)參的時(shí)候?qū)?..args
var args = [1, 2, 3, 4, 5];
// fn2(...args); // 編輯器會(huì)提示語(yǔ)法錯(cuò)誤茫孔,但是可以編譯

==generator函數(shù)==

// function* 函數(shù)名() {} 進(jìn)行定義
function* doSomething() {
    console.log("start");

    yield; // 可以理解為調(diào)試的時(shí)候打斷點(diǎn)

    console.log("finish");
}

// 這樣的函數(shù)必須要用變量存儲(chǔ)起來(lái)
var fn1 = doSomething();
// 使用 .next() 函數(shù)執(zhí)行下一步操作(只會(huì)跑到y(tǒng)ield就停下)再次調(diào)用才會(huì)接著跑
fn1.next();

generator實(shí)際應(yīng)用

/**generator函數(shù)實(shí)際應(yīng)用
 * 模擬買股票
 */
// 定義函數(shù)
function* getStockPrice(stock) {
    // 無(wú)限循環(huán)
    while(true) {
        // .next()被調(diào)用時(shí)會(huì)一直生成 0~100之間的隨機(jī)數(shù)
        yield Math.random()*100; // 假裝在獲取當(dāng)前股票價(jià)格
    }
}

// 獲取函數(shù)
var priceGenerator = getStockPrice("IBM");
// 定義最低價(jià)
var limitPrice = 15;
// 定義當(dāng)前價(jià)
var price = 100;

// 當(dāng)當(dāng)前價(jià) > 最低價(jià)的時(shí)候
while(price > limitPrice) {
    // 調(diào)用函數(shù)獲取當(dāng)前股票值并將值賦給price叮喳。再次進(jìn)入循環(huán)
    price = priceGenerator.next().value;
    // 獲取一定時(shí)間內(nèi)的大于15每股的股票價(jià)格
    console.log(`the gererator return ${price}`);
}

各種“for”循環(huán)

/**
 * for of循環(huán)
 */
var arr = [1,2,3,4];

// forEach(閉包(){})
arr.forEach((element)=> {
    console.log(element);
});

// for(index對(duì)應(yīng)索引 in 數(shù)組)
for(var index in arr) {
    console.log(index); //讀索引
    console.log(arr[index]); //讀值
}

// for(value of arr)
for(var value in arr) {
    // if(value > 1) break; //for of 可以在循環(huán)中break終止循環(huán)
    console.log(value); //讀值
}

// 類定義
class Person {
    name; //屬性
    eat(){
        console.log('我吃');
    } //方法
}

// 實(shí)例化
var p1 = new Person();
p1.name = 'liuhaoyu';
console.log(p1.name);

類 訪問權(quán)限控制

/**
 * 訪問權(quán)限控制符
 */
class Person {
    public name;//默認(rèn)公開          對(duì)象√ 子類√ 自身√

    protected address;//保護(hù)的  對(duì)象× 子類√ 自身√

    private age;//隱私的        對(duì)象× 子類× 自身√
}s

類 構(gòu)造函數(shù) (默認(rèn)private)

class Person {
    // name;
    // age;
    // 構(gòu)造函數(shù)
    // constructor(name:string, age:number) {
    //     this.name = name;
    //     this.age = age;
    //     console.log("實(shí)例化成功");
    // }

    // 可以簡(jiǎn)寫
    constructor(public name:string, public age:number) {
        // 參數(shù)列表里定義帶訪問控制符的屬性被芳,直接可以在實(shí)例化時(shí)創(chuàng)建屬性
    }
}

// 實(shí)例化
var p1 = new Person('liuhaoyu', 500);

繼承

// 爹
class Father {
    public lastName;
    protected money;
    private firstName;
}

// 兒子
class Son extends Father {
    // 兒子 可以繼承姓public 可以繼承錢money 繼承不了名name
}

// 真實(shí)情況
var son = new Son; // 而真是的情況是,實(shí)例化的兒子是拿不出來(lái)錢的(都放爹那了)【對(duì)象不能繼承protected 的 money】

繼承中的super

class Father {
    name;
    money;
    constructor(name, money) {
        this.name = name;
        this.money = money;
    }
    eat() {
        console.log('我能吃');
    }
}

// super()的作用
class Son extends Father {
    age;
    // 1馍悟、在子類的構(gòu)造函數(shù)中充當(dāng)父類的構(gòu)造函數(shù)畔濒,實(shí)例化后使子類的this關(guān)鍵字生效
    constructor(name, money, age) {
        // this.age = age; //錯(cuò)誤必須先實(shí)例化父類
        super(name, money); //先有爹后有兒子:先實(shí)例化爹:這里super()相當(dāng)于調(diào)父類的構(gòu)造函數(shù)
        this.age = age; //super()的作用:讓this關(guān)鍵字生效
    }

    // 2、調(diào)用父類的其他方法
    work() {
        super.eat(); //這里super充當(dāng)了父類
    }
}

==接口:約束類定義==

/**
 * 接口的作用:代碼約定赋朦,是的其他開發(fā)者開調(diào)用某個(gè)方法或者創(chuàng)建新的類的時(shí)候必須遵循接口所定義的規(guī)定
 * “插線板三角插頭只能查三角的篓冲,不帶地線的只能插進(jìn)兩腳插孔”
 */
// 聲明接口 屬性約束
interface Life {
    age: number; //這個(gè)屬性一旦聲明,再實(shí)現(xiàn)的時(shí)候宠哄,是必須的
}
// 采用接口定義的屬性約束類屬性
class Person {
    constructor(public config:Life) {

    }
}
// var p1 = new Person('500'); //錯(cuò)誤
// var p1 = new Person(500); //錯(cuò)誤
var p2 = new Person({
    age: 500,           
}); //參數(shù)得這樣寫: ({接口要求必須的屬性:賦值})

// 聲明接口 必須實(shí)現(xiàn)的方法
interface Animal {
    eat();
}

// 實(shí)現(xiàn) implements
class Sheep implements Animal {
    // 必須寫一個(gè)eat()方法不然會(huì)報(bào)錯(cuò)
    eat() {
        console.log('我吃草');
    }
}
class Tiger implements Animal {
    eat() {
        console.log('我吃肉');
    }
}

generic 泛型約束

/**
 * 泛型 generic
 */
class Person{
    name;
    age;
}

class Student extends Person {
    school;
}

// people:數(shù)據(jù)限制Array<泛型限制Person> : 一個(gè)只能放Person對(duì)象的數(shù)組
var people: Array<Person> = [];
people[0] = new Person;//父類可以放進(jìn)去
people[1] = new Student;//子類可以放進(jìn)去
// people[2] = 1;  //這個(gè)就不行了

模塊

  • 定義和暴露
/**
 * 模塊:
 * 幫助開發(fā)者將代碼分割為可重用的單元壹将。(提高代碼的復(fù)用性,方便管理)
 * 開發(fā)者在模塊定義中決定將模塊中的哪些資源(類毛嫉、方法诽俯、變量) 暴露出去供外部使用
 * 哪些資源只能在模塊能使用(不暴露)
 */

// 定義模塊
export var prop1;
var prop2; //不寫export就不暴露模塊內(nèi)的資源

export function fn1() {

}
function fn2() {

}

export class C1 {

}
class C2 {

}

// 現(xiàn)在一次把暴露所有之前未暴露的資源
export{prop2, fn2, C2};
  • 引入和使用
// 引入 {資源名稱} from "模塊相對(duì)路徑";
import { prop1 } from "./module_export";
// 引入 *所有資源 叫 Modules from "模塊相對(duì)路徑"
import * as Modules from "./module_export";

console.log(prop1);
Modules.fn2();

==模塊注解==

// angularJS 中的模塊注解
// import ( {Component} ) from '@angular/core';

// 這里就是注解
// @Component({
//     selecor: '選擇器',
//     templateUrl: '模板地址.html',
//     StyleUrls: ['樣式地址1.css', '樣式地址2.css']
// })

// 這樣定義一個(gè)組件
// export class Component {
//     // 當(dāng)實(shí)例化這個(gè)組件的時(shí)候,會(huì)通過上面的注解承粤,去找對(duì)應(yīng)的模板地址和對(duì)應(yīng)的樣式地址
//     titile = 'app Works!';
// }

==類型定義文件 .d.ts==

/**
 * 只能白話解釋:
 * 比如我想在angular JS 里面用 jquery 
 * 直接寫$符 ts是不懂得
 * 所以需要下載一個(gè) jquery.d.ts (所有類型定義文件都以.d.ts結(jié)尾)
 * 下載地址是 gitHub上得 DefinetelyTyped(里面托管了幾乎所有的.d.ts)
 * 也可以用 typings (npm install -g typings) **推薦**
 * typings seach 你要的類型定義文件
 * 在項(xiàng)目里安裝 .d.ts文件 (typings install 文件名 --save) 通潮┣框架里已經(jīng)寫好了package.json所以我們不用管--save寫沒寫依賴關(guān)系進(jìn)去
 */
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辛臊,隨后出現(xiàn)的幾起案子仙粱,更是在濱河造成了極大的恐慌,老刑警劉巖彻舰,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伐割,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡刃唤,警方通過查閱死者的電腦和手機(jī)隔心,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)尚胞,“玉大人硬霍,你說(shuō)我怎么就攤上這事×眩” “怎么了唯卖?”我有些...
    開封第一講書人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)躬柬。 經(jīng)常有香客問我耐床,道長(zhǎng),這世上最難降的妖魔是什么楔脯? 我笑而不...
    開封第一講書人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任撩轰,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堪嫂。我一直安慰自己偎箫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開白布皆串。 她就那樣靜靜地躺著淹办,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恶复。 梳的紋絲不亂的頭發(fā)上怜森,一...
    開封第一講書人閱讀 51,679評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音谤牡,去河邊找鬼副硅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛翅萤,可吹牛的內(nèi)容都是我干的恐疲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼套么,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼培己!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起胚泌,我...
    開封第一講書人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤省咨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后玷室,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體零蓉,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年阵苇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片感论。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绅项,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出比肄,到底是詐尸還是另有隱情快耿,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布芳绩,位于F島的核電站掀亥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏妥色。R本人自食惡果不足惜搪花,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撮竿,春花似錦吮便、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至房蝉,卻和暖如春僚匆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搭幻。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工咧擂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粗卜。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓屋确,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親续扔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子攻臀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1、let和const命令 let聲明的變量只在let所在的代碼塊有效纱昧,即有塊級(jí)作用域刨啸,不同于var; let定義...
    風(fēng)之化身呀閱讀 383評(píng)論 0 1
  • 1识脆、新的聲明方式 以前我們?cè)诼暶鲿r(shí)只有一種方法设联,就是使用var來(lái)進(jìn)行聲明,ES6對(duì)聲明的進(jìn)行了擴(kuò)展灼捂,現(xiàn)在可以有三種...
    令武閱讀 1,009評(píng)論 0 7
  • 以下內(nèi)容是我在學(xué)習(xí)和研究ES6時(shí)离例,對(duì)ES6的特性、重點(diǎn)和注意事項(xiàng)的提取悉稠、精練和總結(jié)宫蛆,可以做為ES6特性的字典;在本...
    科研者閱讀 3,128評(píng)論 2 9
  • *node下用express框架的猛,實(shí)現(xiàn)一個(gè)簡(jiǎn)單的mvc *構(gòu)建工具:gulp / babel / webpack ...
    韓娜愛吃辣_前端程序媛閱讀 1,091評(píng)論 0 1
  • [TOC] 參考阮一峰的ECMAScript 6 入門參考深入淺出ES6 let和const let和const都...
    郭子web閱讀 1,781評(píng)論 0 1