es6 課程學習

const和let定義的區別,相同點都是局部做用域,都不能重複聲明,推薦使用const,若是變量會改變值的話再使用let,由於const能夠提醒咱們這個不能被改變,const符合函數式變成,js編譯器對const進行了優化,處理機制不一樣。php

const定義的是內存中的塊,若是定義的是對象,是能夠修改的,可是若是是基本數據類型就不能修改了。es6

1. 解構模式,解構的內部變量是怎麼聲明的,前面是什麼聲明的就是什麼聲明的,如:ajax

function test(){數組

  return {a: 123, b: 345};promise

}瀏覽器

const {a,b} = test();數據結構

這裏的, a,b就是用const聲明的閉包

若是是數組是這種寫法app

const s = ['🍌', '🍊', '🍎'];async

const [c, d, e] = s;

函數參數默認值,參數的解構,擴展運算符

2. 字符串新增的方法:

s.startsWith(), s.endsWith(),s.includes()....

解析字符串模版的方法,兩個參數都是數組

const s = 'hello';

const e = 'world';

const c = test`foor ${s} ${e} bar`;  //加了()就是直接傳的參數,沒有第二個參數了

function test(strs, ...values){ //...擴展運算符

  console.log(values); //arr

  console.log(strs); //arr

}

 strs的值是: ["foor ", " ", " bar"]

0:"foor "

1:" "

2:" bar"

至關於中間的兩個變量將字符串分割成了三部分

3. 數組新增的方法

Array.from(str| arguments)

...擴展運算符的應用

const s = 'dfhajf';

const arr = Array.from(s);

const arr1 = [1,2,...s];

4. 對象

支持變量爲key值,用 [ ] 包裹

Object.assign(),

屬於淺拷貝,將屬性合併到第一個對象上,複製對象:

var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
var o1 = { a: 1, b: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, 注意目標對象自身也會改變。

屬性會被後續參數中的相同屬性覆蓋。

下面是深拷貝的例子

obj1 = { a: 0 , b: { c: 0}};
let obj3 = JSON.parse(JSON.stringify(obj1));
obj1.a = 4;
obj1.b.c = 4;
console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}

Object.assign()拷貝的是可枚舉的屬性,原型鏈中的屬性和不可枚舉的屬性不能拷貝

原始類型會被包裝成對象,根據自身的可枚舉屬性,若是不可枚舉則不會被拷貝

var v1 = 'abc';
var v2 = 10;
var v3 = Symbol('foo');
var obj = Object.assign({},v1, v2, null, undefined, v3);
//null 和undefined會被忽略
//只有字符串的包裝對象有可枚舉屬性
console.log(obj);
// {0: a, 1: b, 2: c}

異常會打斷後續拷貝任務,好比遇到只讀屬性的時候,

var target = Object.defineProperty({},'foo',{
            value: 1,
            writable: false
        })
Object.assign(target, {bar:2},{foo2: 3,foo: 2, foo3: 4},{baz: 4});
console.log(target);

字面量的對象經過__proto__能夠修改prototype的值

const drink = {

  getDrink(){

    return "pijiu"

  }

}

const sunday = {

  __proto__: drink,

}

Object.setPrototypeOf(sunday, drink);   //和上面的代碼等價

sunday.getDrink();

上面能夠當作是繼承,Sunday繼承drink中的屬性和方法,若是sunday想在內部調用drink中的話

繼承 用super

 

Object.is() 判斷兩個值是否是相等

Object.is(NaN, NaN)  //true

 

 

類的聲明(class),es6實現了類的語法糖,可是和以前的聲明仍是有區別,區別是:

a. 類的聲明不會存在提高,至關於使用let和const聲明的,真正執行語句以前,它們會一直存在與臨時死區中;

b. 類中的全部方法都是不可枚舉的,在以前的聲明中沒有這個限制,只有經過Object.defineProperty(obj, "name", {value: '99', enumerable: false})定義的方法纔會是不可枚舉的

c. 類的名稱在聲明的內部是不可修改的,在外部能夠,由於在內部至關於用const聲明的類名,而在外部至關於用let聲明的名字

d. 類的聲明只能經過new調用,普通調用會報錯,由於每一個類都含有一個名爲[[Construct]]的內部方法,經過關鍵字new調用那些不含有[[Construct]]的方法會報錯;

e. 類聲明中全部的代碼自動運行在嚴格模式下,並且沒法強行脫離嚴格模式

class Person{
    constructor(name){
        this.name = name;
    }
    sayName(){
        console.log(this.name)
    }
}
let man = new Person('xx');
man.sayName();

下面是經過其餘方式實現的,可見代碼量的區別

let Person2 = (function(){
    "use strict"
    const Person2 = function(name){
        if(typeof new.target === 'undefined'){
            throw new Error("必須經過關鍵字new調用構造函數");
        }
        this.name = name;
    }
    Object.defineProperty(Person2.prototype, 'sayName',{
        value: function(){
            if(typeof new.target !== 'undefined'){
                throw new Error("不可以使用關鍵字new調用該方法");
            }
            console.log(this.name)
        },
        enumerable: false,
        writable: true,
        configurable: true
    })
    return Person2;
})();
let woman = new Person2('ccc');
console.log(woman.sayName());

須要重點理解這個自執行函數,class是順序執行的,並非new的時候纔會調用,因此若是方法名或屬性名是變量的話,在類聲明下面再修改的話也不會生效了,使用的是類前面的值

new操做符的執行過程

1. 一個繼承自prototype的新對象被建立,經過__proto__屬性指向原型對象(prototype)

2. 使用指定的參數調用構造函數 (函數的名字),並將this綁定到新建立的對象

3. 由構造函數返回的對象就是new表達式的結果,若是構造函數沒有返回值的話,就使用第一步的對象(通常狀況下,都沒有返回值,若是用戶想返回不一樣的對象能夠本身定義,若是返回的不是對象呢,而是基本的數據類型,則忽略不計,仍然使用第一步的對象)

 

理解原型對象,原型鏈

每建立一個新函數就會生成一個對應的原型對象,經過prototype屬性鏈接,prototype中存儲的是指針

原型對象中會有一個constructor屬性,這個屬性存儲的也是一個指針,指向新函數,因此這是一個循環的過程

建立對象,繼承對象的新方法,super是語法糖,原理仍是原型鏈的繼承,Object.create(newO, o.prototype) 

5. 函數

增長了一個fn.name

箭頭函數,的this是父級的this。

函數參數,默認參數直接在形參中指定

this的指向

6. Iterator, Generator

Iterator是一個數據結構,須要有next()一步一步向下執行,和Generator函數結合使用

var fn = function *(){

  yield '22';

  yield '33';

}

const result = fn();

result.next();

result.next();

result.next();

 

co模塊是什麼東東

for of 是有Symbol.iterator屬性的對象才能使用

for in 有什麼問題

for in遍歷數組的話  遍歷順序有可能不是按照數組的實際順序,會遍歷數組的全部屬性,包括原型上新定義的

for of只是遍歷數組的值,不包括原型上的,還有自定義的非索引值

 class類的定義,語法糖 

class Person{

  constructor(name){

    this.name = name;

  }

  sayName(){

    console.log(this.name)

  }

}

class Teacher extends Person{

  constructor(name){

    super(name);

  }

  sayName(){

    super.sayName();

    ...

  }

}

 

7. Set, Map

Set的方法

let arr = new Set('12444');

arr.add('33');

arr.add('34');

arr.has('1');

arr.delete('34');

for(let data of arr){

  console.log(data);

}

arr.clear();

console.log(arr.size)

Set能夠直接去重,上面初始化的時候會生成 1 2 4,

Set是沒有length屬性的,有 size屬性

Set沒有key值,Map有key值,key值和value值能夠是任何類型

Map的方法:

let map = new Map();

let fruit = {}, obj = function(){};

map.set(fruit,'32');

map.set( obj,'3233');

for(let item of map){

  console.log(item); //打印的是完整的一項

}

map.get(fruit);

map.size;

map.delete(fruit);

map.clear();

 

數組去重的方法

let arr = [1,3,4,5,1,2,3,4,5];

let result = [...new Set(arr)];

對於es6及以後的語法,能夠轉換成es5的查看實現過程,也叫原理

 

module的兩種不一樣寫法

a.

function test(){}

function gogo(){}

export test;

export gogo;

//export {test, gogo};

import {test, gogo} from 'index.js'

解構

b. 

export default {test, gogo}

import data from 'index.js'

data.test();

data.gogo();

 

8. async awite promise fetch

(async(){

  function promisefn(url){

    return new Promise(function(resolve, reject){

      $.ajax({

        url: url,

        success(res){

          resolve(res);

        },

        error(){

          reject('error');

        }

      })

    })    

  }

  const a1 = await promistfn('http://www.xxx.com/a');

  const a2 = await promistfn('http://www.xxx.com/b');

  let p = a1 + a2;

  console.log(p);

})

async await 也是經過promise對象來實現的。

 

修飾器 decorator

function testable(target){

  target.isTestable = true;

}

@testable

class myTestableClass{}

console.log(myTestableClass.isTestable);

修飾器對類的行爲的改變,是代碼編譯時發生的,而不是運行時。這意味着,修飾器能在編譯階段運行代碼

core-decorators.js庫

 

瀏覽器有兩個發請求的東西,一個是navigator.sendBeacon('a.php')作埋點用的,
一個是類ajax請求fetch('a.php')

 

symbol 惟一的

 

9. 數據類型

基本數據類型 6種了,Boolean,Number,String,null,undefined,Symbol

複雜數據類型統稱爲Object,新增的Set 和 Map 也是一個對象吧?

const obj = { name: 'www'};

obj.age = '333';  //不會報錯,也就是能夠添加,刪除,修改屬性值,可是不能改變對象的地址

obj = [];  //會報錯

10. label statement  (語句優先)

 

11.自執行函數

操做符後面都是表達式

var b = 10;
(function b(){
b = 20;
console.log(b);
})();
console.log(b);

這個的運行結果想不通?

12.高階函數,把函數看成參數或返回值的函數的函數

回調函數,閉包(函數,環境),惰性函數,柯里化(容許使用部分函數參數來生成函數),尾遞歸優化,反柯里化

ranmod

 

做用域的種類:

全局做用域,函數做用域,塊級做用域(es6)

做用域鏈

變量與函數聲明提早(變量提高)

this的指向,call,apply,bind

原型對象和原型鏈

構造函數的返回值,正常是不寫返回值,但返回的是實例對象,特殊狀況是寫了返回值,return 簡單的數據類型,返回的仍是實例,若是返回的是對象類型,那返回的就是這個對象

if(!("userName" in window)){
var userName = 'zhengzheng.xz';
}
console.log(userName);  //undefined

變量提高

圓形對象中的constructor

Person.prototype.constructor === Person;

Function.prototype.constructor === Function;

Object.prototype.constructor === Object;

Object.constructor === Function; //這個是爲何呢

 

題:

var name = "global";

function A(name){

  alert(name);   //實參就是 變量賦值,至關於前面有一個var name  = name; 阻止了下面的變量提高,由於直接賦值了

  this.name = name;

  var name = '1';

}

A.prototype.name = '2';

var a = new A('3');

alert(a.name);

delete a.name;

alert(a.name);

 

function fun(n,o){

  console.log(o);

  return {

    fun: function(m){

      return fun(m,n);

    }

  }

}

var a = fun(0);

a.fun(1);

a.fun(2);

var b = fun(0).fun(1).fun(2).fun(3);

var c = fun(0).fun(1);

c.fun(2);

c.fun(3);

相關文章
相關標籤/搜索