ES6 新特性 set map promise

# **數組中 ** # 
              find()  找出第一個符合條件的數組成員  沒有  返回undefined
            findIndex()找出第一個符合條件的數組成員的下標  沒有返回-1  可以發現NaN  彌補indexof的不足
             rest參數   創建數組      該變量將多餘的參數放入數組中                   互爲逆運算 擴展運算符    ...將一個數組轉換爲逗號分隔的參數序列
           循環用for  of
           數組去重     [...new Set([1,2,3,4,4,4,5])]
                              Array.from(new Set(arr))
   es6的新特性 
                         簡潔:
                                 允許直接寫入變量和函數  作爲對象的屬性和方法  這樣書寫更爲簡潔

                         緊密:
                               第七種數據類型Symbol  表示獨一無二的值,用於區別對象中相同的屬性及值
                              新增的兩種數據結構   Set  Map

const 申明一個只讀的常量  聲明時必須賦值 一旦申明  值就不能更改  不存在變量提升,同樣存在暫時性死區,同樣不可以重複聲明
let 擁有塊級作用域,不存在變量提升,不允許在相同的作用域下 重複申明同一個變量  不能在函數內部重新申明參數
## Set  沒有重複值的類似於數組的一種數據集合 ##
set屬性  構造函數 constructor  成員數size
set四個操作方法 :
        //Set四個操作方法。
//        •    add(value):添加某個值,返回Set結構本身。
//        •    delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
//        •    has(value):返回一個布爾值,表示該值是否爲Set的成員。
//        •    clear():清除所有成員,沒有返回值。
        
        //        四個遍歷方法,可以用於遍歷成員。for of 遍歷Set
//        •    keys():返回鍵名的遍歷器   鍵名的集合
//        •    values():返回鍵值的遍歷器  鍵值的集合
//        •    entries():返回鍵值對的遍歷器  名值對的集合
//        •    forEach():使用回調函數遍歷每個成員  
Array.from()將兩類對象轉換爲真正的數組,   兩類對象-類似數組的對象和可遍歷的對象Itearator接口  Set Map        
Array.of() 將一組值轉換爲數組   可以替代Array()  new Array()
find()  找出第一個符合條件的數組成員  沒有  返回undefined
findIndex()找出第一個符合條件的數組成員的下標  沒有返回-1  可以發現NaN  彌補indexof的不足

Map  鍵值對的集合  鍵值對的一種數據結構   鍵可以是各種類型的數據結構 
//        Object  本質也是鍵值對的集合  Hash結構   只能用字符串當做鍵
              
        //        Map五個操作方法 :
        //操作方法。
//        •    set()  get()
//        •    delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
//        •    has(value):返回一個布爾值,表示該值是否爲Set的成員。
//        •    clear():清除所有成員,沒有返回值。

js預解析,全盤掃描,沒有定義先使用的變量定義爲undefined,沒有調用就使用的函數,把定義該函數的字符串賦值給該函數名;參數

es6新特性:
      Symbol  表示獨一無二的值    第七種數據類型   產生 區別對象中相同的屬性及值
      允許直接寫入變量和函數  作爲對象的屬性和方法  這樣書寫更爲簡潔
      set   map   允許我們使用箭頭來定義函數
    擴展運算符,將一個數組轉換爲逗號分隔的參數序列
     rest參數    形式(...變量名)  獲取函數的所有參數               rest參數搭配的變量是一個數組的話 該變量將多餘的參數放入數組中

      嚴謹性,let聲明變量,const聲明常量,塊級作用域的問題 避免了全局污染,js預解析
     promise  的狀態
       解構賦值
      number  bool  對象  
    
      for of    Array of  Array from 
      模板字符串
       數據解構 set map
   不存在js預解析,避免了全局變量的污染   let const 的使用,一定要先定義再使用 

ECMAScript6 新特性

 

String

startsWith() //檢查是否以指定字符串開頭,返回布爾值

let str = 'javascript';

str.startsWith('java');  //true

 

endsWith() //檢查是否以指定字符串結尾,返回布爾值

let str = 'javascript'

str.endsWith('pt');

 

includes() //檢查字符串是否包含指定字符串 ,返回布爾值

let str = 'javascript';

str.includes('j',1);//可以傳入兩個參數 查詢的項 以及起始位置

 

repeat() //指定字符串重複次數

let str = 'javascript';

str.repeat('3');

 

Array

 

find :

let arr=[1,2,234,'sdf',-2];

arr.find(function(x){

    return x<=2;

})//結果:1,返回第一個符合條件的x值

arr.find(function(x,i,arr){

    if(x<2){console.log(x,i,arr)}

})//結果:1 0 [1, 2, 234, "sdf", -2],-2 4 [1, 2, 234, "sdf", -2]

find的參數爲回調函數,回調函數可以接收3個參數,值x、所以i、數組arr,回調函數默認返回值x。

 

 

●findIndex :

let arr=[1,2,234,'sdf',-2];

arr.findIndex(function(x){

    return x<=2;

})//結果:0,返回第一個符合條件的x值的索引

arr.findIndex(function(x,i,arr){

    if(x<2){console.log(x,i,arr)}

})//結果:1 0 [1, 2, 234, "sdf", -2],-2 4 [1, 2, 234, "sdf", -2]

findIndex和find差不多,不過默認返回的是索引。

 

●includes:

let arr=[1,2,234,'sdf',-2];

arr.includes(2);// 結果true,返回布爾值

arr.includes(20);// 結果:false,返回布爾值

arr.includes(2,3)//結果:false,返回布爾值

includes函數與string的includes一樣,接收2參數,查詢的項以及查詢起始位置。

 

 

●keys:

let arr=[1,2,234,'sdf',-2];

for(let a of arr.keys()){

    console.log(a)

}//結果:0,1,2,3,4  遍歷了數組arr的索引

keys,對數組索引的遍歷

 

 

●values:

let arr=[1,2,234,'sdf',-2];

//查詢

for(let a of arr.values()){

    console.log(a)

}//結果:1,2,234,sdf,-2 遍歷了數組arr的值

keys,對數組項的遍歷

 

●entries:

let arr=['w','b'];

for(let a of arr.entries()){

    console.log(a)

}//結果:[0,w],[1,b]

for(let [i,v] of arr.entries()){

    console.log(i,v)

}//結果:0 w,1 b

entries,對數組鍵值對的遍歷。

 

 

●fill:

let arr=['w','b'];

arr.fill('i')//結果:['i','i'],改變原數組

arr.fill('o',1)//結果:['i','o']改變原數組,第二個參數表示填充起始位置

new Array(3).fill('k').fill('r',1,2)//結果:['k','r','k'],第三個數組表示填充的結束位置

fill方法改變原數組,當第三個參數大於數組長度時候,以最後一位爲結束位置。

 

Array.of():

Array.of('w','i','r')//["w", "i", "r"]返回數組

Array.of(['w','o'])//[['w','o']]返回嵌套數組

Array.of(undefined)//[undefined]依然返回數組

Array.of()//[]返回一個空數組

Array.of()方法永遠返回一個數組,參數不分類型,只分數量,數量爲0返回空數組。

 

 

●copyWithin:

["w", "i", "r"].copyWithin(0)//此時數組不變

["w", "i", "r"].copyWithin(1)//["w", "w", "i"],數組從位置1開始被原數組覆蓋,只有1之前的項0保持不變

["w", "i", "r","b"].copyWithin(1,2)//["w", "r", "b", "b"],索引2到最後的r,b兩項分別替換到原數組1開始的各項,當數量不夠,變終止

["w", "i", "r",'b'].copyWithin(1,2,3)//["w", "r", "r", "b"],強第1項的i替換爲第2項的r

 

copyWithin方法接收三個參數,被替換數據的開始處、替換塊的開始處、替換塊的結束處(不包括);copyWithin(s,m,n).

 

●Array.from():

Array.from({'0':'w','1':'b',length:2})//["w", "b"],返回數組的長度取決於對象中的length,故此項必須有!

Array.from({'0':'w','1':'b',length:4})//["w", "b", undefined, undefined],數組後2項沒有屬性去賦值,故undefined

Array.from({'0':'w','1':'b',length:1})//["w"],length小於key的數目,按序添加數組

 

let divs=document.getElementsByTagName('div');

Array.from(divs)//返回div元素數組

Array.from('wbiokr')//["w", "b", "i", "o", "k", "r"]

Array.from([1,2,3],function(x){

        return x+1})//[2, 3, 4],第二個參數爲回調函數

 

Array.from可以把帶有lenght屬性類似數組的對象轉換爲數組,也可以把字符串等可以遍歷的對象轉換爲數組,它接收2個參數,轉換對象與回調函數

 

Function

1解決設置參數默認值

function test(a,b="world"){

console.log(a+b)

}

test("hello")    // helloworld

//等同於

function  test(a,b){

b=b || "world"

console.log(a+b)

}

test("hello")

 

2,作用域問題

{

let x = "hello"

function fn(x,y=x){

console.log(x,y)

}

fn("kk")  //kk,kk

}

{

let x = "hello"

function fn(c,y=x){

console.log(c,y)

}

fn("kk")  //kk,hello

}

3,rest參數 會自動轉化成數組

{

function test(...arg){

for(var item of arg){

console.log("rest" + item)

}

}

test(1,2,3,4,"a")

}

 

4,擴展運算符 ...

{

console.log(...[1,2,3])

}

 

5,箭頭函數  

{

let fn = m => m*3

console.log(fn(2)) //6

//等同於

let fn =function(m){

return m*3

}

}

 

{

let fn = (m*n) => m*n

console.log(fn(2,5)) //10

}

 

{

let fn = (a,b,c="了不起") => {

console.log(a+b+c)

}

fn("真","子")

}

箭頭函數注意點

  1. typeof運算符和普通的function一樣
  2. instanceof也返回true,表明也是Function的實例

3.this固定,不再善變

4.箭頭函數不能用new

5.不能使用arguments

 

 

 

Object

1、屬性的簡潔表示法

 

ES6允許直接寫入變量和函數,作爲對象的屬性和方法。這樣的書寫更加簡潔。

var foo = 'bar';  

var baz = {foo};  

baz  {foo: "bar"}  

// 等同於  

var baz = {foo: foo};  

上面代碼表明,ES6允許在對象之中,只寫屬性名,不寫屬性值。這時,屬性值等於屬性名所代表的變量。

下面這種寫法也可以

function f(x, y) {  

  return {x, y};  

}  

// 等同於  

function f(x, y) {  

  return {x: x, y: y};  

}  

f(1, 2) // Object {x: 1, y: 2}

 

  

除了屬性簡寫,方法也可以簡寫。

var o = {  

  method() {  

    return "Hello!";  

  }  

};  

// 等同於  

var o = {  

  method: function() {  

    return "Hello!";  

  }  

};  

 

2比較是否相等 嚴格相等 ===

{

console.log(-0 == +0) //true

Object.is(-0,+0) //false

}

 

 

常用的對象api

NO1:對象拼接

{

let obj1 = {a:1}

let obj2 = {b:2}

Object.assign(obj1,obj2)  // {a:1,b:2}

}

後面的參數target是目標對象,後面可以跟若干個源對象,此API的作用是將多個源對象拼接在目標對象之後,組成一個對象。

 

NO2:創建一個對象

{

let obj1 = {name:"lee"};

let obj2 = Object.create(obj1)

console.log(obj2.name) //lee

console.log(obj2) //{}

}

用此方法創建一個對象,新創建的對象會繼承“原型對象”的屬性,但這些屬性並不是新創建對象本身的屬性

 

 

N03,凍結對象  凍結之後就不能在修改了

{

let obj = {name:"lee"}

let obj2 = Object.freeze(obj);

obj2.name = "wang";

console.log(obj , obj2)

}

 

Set

基本用法

ES6提供了新的數據結構Set。它類似於數組,但是成員的值都是唯一的,沒有重複的值。

Set本身是一個構造函數,用來生成Set數據結構。

 

var s = new Set();

[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));

for (let i of s) {

  console.log(i);

}// 2 3 5 4

 

上面代碼通過add方法向Set結構加入成員,結果表明Set結構不會添加重複的值。

Set函數可以接受一個數組(或類似數組的對象)作爲參數,用來初始化。

 

// 例一var set = new Set([1, 2, 3, 4, 4]);

[...set]// [1, 2, 3, 4]

// 例二var items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);

items.size // 5

// 例三function divs () {

  return [...document.querySelectorAll('div')];

}

var set = new Set(divs());

set.size // 56

// 類似於

divs().forEach(div => set.add(div));

set.size // 56

 

上面代碼中,例一和例二都是Set函數接受數組作爲參數,例三是接受類似數組的對象作爲參數。

上面代碼中,也展示了一種去除數組重複成員的方法。

// 去除數組的重複成員

[...new Set(array)]

向Set加入值的時候,不會發生類型轉換,所以5"5"是兩個不同的值。Set內部判斷兩個值是否不同,使用的算法叫做“Same-value equality”,它類似於精確相等運算符(===),主要的區別是NaN等於自身,而精確相等運算符認爲NaN不等於自身。在Set內部,兩個NaN是相等。

 

Set實例的屬性和方法

Set結構的實例有以下屬性。

  • Set.prototype.constructor:構造函數,默認就是Set函數。
  • Set.prototype.size:返回Set實例的成員總數。

Set實例的方法分爲兩大類:操作方法(用於操作數據)和遍歷方法(用於遍歷成員)。下面先介紹四個操作方法。

  • add(value):添加某個值,返回Set結構本身。
  • delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
  • has(value):返回一個布爾值,表示該值是否爲Set的成員。
  • clear():清除所有成員,沒有返回值。

上面這些屬性和方法的實例如下。

 

s.add(1).add(2).add(2);// 注意2被加入了兩次

s.size // 2

s.has(1) // true

s.has(2) // true

s.has(3) // false

s.delete(2);

s.has(2) // false

 

Array.from方法可以將Set結構轉爲數組。

var items = new Set([1, 2, 3, 4, 5]);var array = Array.from(items);

這就提供了去除數組重複成員的另一種方法。

function dedupe(array) {

  return Array.from(new Set(array));

}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

遍歷操作

Set結構的實例有四個遍歷方法,可以用於遍歷成員。

  • keys():返回一個鍵名的遍歷器
  • values():返回一個鍵值的遍歷器
  • entries():返回一個鍵值對的遍歷器
  • forEach():使用回調函數遍歷每個成員

key方法、value方法、entries方法返回的都是遍歷器對象。由於Set結構沒有鍵名,只有鍵值(或者說鍵名和鍵值是同一個值),所以key方法和value方法的行爲完全一致。

 

let set = new Set(['red', 'green', 'blue']);

for (let item of set.keys()) {

  console.log(item);

}// red

// green

// blue

for (let item of set.values()) {

  console.log(item);

}// red

// green

// blue

for (let item of set.entries()) {

  console.log(item);

}// ["red", "red"]

// ["green", "green"]

// ["blue", "blue"]

 

Set結構的實例默認可遍歷,它的默認遍歷器生成函數就是它的values方法。

Set.prototype[Symbol.iterator] === Set.prototype.values// true

這意味着,可以省略values方法,直接用for...of循環遍歷Set。

WeakSet

WeakSet結構與Set類似,也是不重複的值的集合。但是,它與Set有兩個區別。

首先,WeakSet的成員只能是對象,而不能是其他類型的值。

其次,WeakSet中的對象都是弱引用,即垃圾回收機制不考慮WeakSet對該對象的引用,也就是說,如果其他對象都不再引用該對象,那麼垃圾回收機制會自動回收該對象所佔用的內存,不考慮該對象還存在於WeakSet之中。這個特點意味着,無法引用WeakSet的成員,因此WeakSet是不可遍歷的。

var ws = new WeakSet();

ws.add(1)// TypeError: Invalid value used in weak setws.add(Symbol())// TypeError: invalid value used in weak set

上面代碼試圖向WeakSet添加一個數值和Symbol值,結果報錯,因爲WeakSet只能放置對象。

WeakSet是一個構造函數,可以使用new命令,創建WeakSet數據結構。

var ws = new WeakSet();

作爲構造函數,WeakSet可以接受一個數組或類似數組的對象作爲參數。(實際上,任何具有iterable接口的對象,都可以作爲WeakSet的參數。)該數組的所有成員,都會自動成爲WeakSet實例對象的成員。

WeakSet結構有以下三個方法。

  • WeakSet.prototype.add(value):向WeakSet實例添加一個新成員。
  • WeakSet.prototype.delete(value):清除WeakSet實例的指定成員。
  • WeakSet.prototype.has(value):返回一個布爾值,表示某個值是否在WeakSet實例之中。

下面是一個例子。

 

var ws = new WeakSet();var obj = {};var foo = {};

ws.add(window);

ws.add(obj);

ws.has(window); // true

ws.has(foo);    // false

ws.delete(window);

ws.has(window);    // false

 

WeakSet沒有size屬性,沒有辦法遍歷它的成員。

WeakSet不能遍歷,是因爲成員都是弱引用,隨時可能消失,遍歷機制無法保證成員的存在,很可能剛剛遍歷結束,成員就取不到了。WeakSet的一個用處,是儲存DOM節點,而不用擔心這些節點從文檔移除時,會引發內存泄漏。

 

Map

Map對象就是簡單的鍵值對映射。其中的鍵和值可以使任意值。(ps : 對象的鍵只能是字符串 )

  1. 創建Map實例的兩種方法

    //1.

    var map = new Map();

map.set('one', 1);

map.set('two', 2);

    map.set('three', 3);

    //2.

    var map = new Map([['one',1], ['two', 2], ['three', 3]]);

2.鍵的比較

鍵的比較規則:NaN 是與NaN是相同的(雖然NaN !== NaN),除此之外所有的值都根據'==='判斷。

    var map = new Map();

    map.set(Number('aa111'), 'isNaN');

    map.set(Number('bb222'), 'also is NaN');

    map.get(NaN);    //'also is NaN'

3.Map VS Object

一個對象通常都有自己的原型,所以一個對象總有一個"prototype"鍵。不過,從ES5開始可以使用map = Object.create(null)來創建一個沒有原型的對象

一個對象的鍵只能是字符串或者Symbols,但一個Map的鍵可以是任意值。

你可以通過size屬性很容易地得到一個Map的鍵值對個數,而對象的鍵值對個數只能手動確認。

4.Map屬性

Map.length 屬性length的值爲0。

Map.prototype 表示Map構造器的原型。允許添加屬性從而應用與所有的Map對象。

  1. Map實例 - 所有Map對象的實例都會繼承Map.prototype。
  2. 屬性

Map.prototype.constructor 返回創建給map實例的構造函數,默認是Map函數。

Map.prototype.size 返回Map對象的鍵值對的數量。

    var map = new Map([['one',1], ['two', 2], ['three', 3]]);

    console.log(map.constructor); //function Map() { [native code] }

    console.log(map.size); //3

方法

    //Iterator對象:可以使用for..of進行迭代的對象

    var map = new Map([[1, 'one'],[2, 'two'], [3, 'three']]);

1.Map.prototype.clear() 移除Map對象的所有鍵值對。

    console.log(map.size);    //3

    map.clear();

    console.log(map.size);    //0

2.Map.prototype.delete(key) 移除任何與鍵相關聯的值,並且返回該值,該值在之前會被Map.prototype.has(key)返回爲true。之後再調用則返回false。

    console.log(map.has(1));    //true

    map.delete(1);

    console.log(map.has(1));    //false

3.Map.prototype.entries() 返回一個新的Iterator對象,它按插入順序包含了Map對象中每個元素的[key, value]數組。

    console.log(map);    //Map {1 => "one", 2 => "two", 3 => "three"}

    map.entries();

    console.log(map);    //Map {1 => "one", 2 => "two", 3 => "three"}

4.Map.prototype.forEach(callbackFn[, thisArg]) 按插入順序,爲Map對象裏的每一鍵值對調用一次callbackFn函數。如果爲forEach提供了thisArg,他將在每次回調函數中作爲this值。

    map.forEach(function(value, key, mapObj) {

        console.log(value + '---' + key + '---' + mapObj);

        //value - Map對象裏每一個鍵值對的值

        //key - Map對象裏每一個鍵值對的鍵

        //mapObj - Map對象本身

        console.log(this); //this === window

    });

    map.forEach(function(value, key, mapObj) {

        console.log(value + '---' + key + '---' + mapObj);

        console.log(this);    //this === map

    }, map)

5.Map.prototype.get(key) 返回鍵對應的值,如果不存在,則返回undefined。

    map.get(1); //'one'

6.Map.prototype.has(key) 返回一個布爾值,表示Map實例是否包含鍵對應的值。

    map.has(1); // true

    map.has(5); //false

7.Map.prototype.keys() 返回一個新的Iterator對象,它按插入順序包含了Map對象中每個元素的鍵。

    map.keys();    //MapIterator {1, 2, 3}

8.Map.prototype.set(key, value) 設置Map對象中鍵的值,返回該Map對象。

    console.log(map.has(4));    //false

    map.set(4, 'four');

    console.log(map.has(4))    //true

9.Map.prototype.values() 返回一個新的Iterator對象,它按插入順序包含了Map對象中每個元素的值。

    map.values(); //

6.使用for..of方法迭代映射

    var map = new Map();

    map.set(1, 'one');

    map.set(2, 'two');

    for (var [key, value] of map) {

        console.log(key + '---' + value);

    }

    // 1 --- one 2 --- two

    for (var key of map.keys()) {

        console.log(key);

    }

    // 1 2

    for (var value of map.values()) {

        console.log(value);

    }

// 'one' 'two

 

 

Promise

相信凡是寫過javascript的童鞋也一定都寫過回調方法(callback),簡單說回調方法就是將一個方法func2作爲參數傳入另一個方法func1中,當func1執行到某一步或者滿足某種條件的時候才執行傳入的參數func2,例如下面的代碼段

 

// 當參數a大於10且參數func2是一個方法時 執行func2

function func1(a, func2) {

    if (a > 10 && typeof func2 == 'function') {

        func2()

    }

}

 

func1(11, function() {

    console.log('this is a callback')

})

 

一般來說我們會碰到的回調嵌套都不會很多,一般就一到兩級,但是某些情況下,回調嵌套很多時,代碼就會非常繁瑣,會給我們的編程帶來很多的麻煩,這種情況俗稱——回調地獄。

由此,Promise的概念就由社區提出並實現,作用與回調方法幾乎一致,都是在某種情況下執行預先設定好的方法,但是使用它卻能夠讓代碼變得更簡潔清晰

 

什麼是Promise

 

Promise是異步編程的一種解決方案,它有三種狀態,分別是pending-進行中resolved-已完成rejected-已失敗

當Promise的狀態又pending轉變爲resolved或rejected時,會執行相應的方法,並且狀態一旦改變,就無法再次改變狀態,這也是它名字promise-承諾的由來

案例

function fn(ready){

//返回 promise的實例

return new Promise((resolve,reject)=>{

if(ready){  //true

resolve("成功了")  //返回唯一的值

}else{

reject("錯了")  //失敗返回唯一值

}

})

}

fn(0).then(function(a){    //then  //catch

console.log(a)}).catch(function(a){

console.warn(a)

})

 

class基本用法和繼承

//生成一個父類

class Parent{

//構造器

constructor(name="wang"){

this.name = name; //this會指向構造函數new出來的實例對象

this.say=function(){

console.log(this.name)

}

}

}

class Child extends Parent{

constructor(name="sun"){

super(name)//改變默認值

}

get newName(){

return this.name + " gaga "

}

set newName(value){

this.name = value

}

}

 

let person1 = new Child();

person1.say()

console.log(person1.newName)

person1.newName="sssss"

console.log(person1.newName)

 

Symbol

爲啥需要Symbol

一個新規則的提出,必然是因爲有需求,熟悉ES5的人都知道,ES5裏面對象的屬性名都是字符串,如果你需要使用一個別人提供的對象,你對這個對象有哪些屬性也不是很清楚,但又想爲這個對象新增一些屬性,那麼你新增的屬性名就很可能和原來的屬性名發送衝突,顯然我們是不希望這種情況發生的。所以,我們需要確保每個屬性名都是獨一無二的,這樣就可以防止屬性名的衝突了。因此,ES6裏就引入了Symbol,用它來產生一個獨一無二的值。

 

Symbol是什麼

 

我們已經知道ES6中引入了一個叫Symbol的東西,但是這個東西到底是什麼呢?是一個函數還是一個對象或者是其他什麼?Symbol實際上是ES6引入的一種原始數據類型,除了Symbol,JavaScript還有其他6種數據類型,分別是Undefined、Null、Boolean、String、Number、對象,這5種數據類型都是ES5中就有的。

 

怎麼生成一個Symbol類型的值

 

既然我們已經知道了Symbol是一種原始的數據類型,那麼怎麼生成這種數據類型的值呢?Symbol值是通過Symbol函數生成的,如下:

 

let s = Symbol();console.log(s);  // Symbol()typeof s;  // "symbol"

 

上面代碼中,s就是一個Symbol類型的值,它是獨一無二的。

 

Symbol函數前不能用new

 

Symbol函數不是一個構造函數,前面不能用new操作符。所以Symbol類型的值也不是一個對象,不能添加任何屬性,它只是一個類似於字符型的數據類型。如果強行在Symbol函數前加上new操作符,會報錯,如下:

 

let s = new Symbol();// Uncaught TypeError: Symbol is not a constructor(…)

 

Symbol函數的參數

 

字符串作爲參數

 

用上面的方法生成的Symbol值不好進行區分,Symbol函數還可以接受一個字符串參數,來對產生的Symbol值進行描述,方便我們區分不同的Symbol值。

 

let s1 = Symbol('s1');

let s2 = Symbol('s2');

console.log(s1);  

// Symbol(s1)console.log(s2);  

// Symbol(s2)

s1 === s2;  //  false

let s3 = Symbol('s2');

s2 === s3;  //  false

 

從上面代碼可以看出:

 

 

  1. 給Symbol函數加了參數之後,控制檯輸出的時候可以區分到底是哪一個值;

 

  1. Symbol函數的參數只是對當前Symbol值的描述,因此相同參數的Symbol函數返回值是不相等的;
  2.  

Symbol.for()和Symbol.keyFor()

 

Symbol.for()函數也可以用來生成Symbol值,但該函數有一個特殊的用處,就是可以重複使用一個Symbol值。

 

let s7 = Symbol.for('s7');

console.log(s7); // Symbol(s7)

s7.toString(); // "Symbol(s7)"

let s8 = Symbol.for('s8');

s7 === s8

//  truelet s9 = Symbol();

Symbol.keyFor(s9);

// undefinedSymbol.keyFor(s8); // "s8"

 

Symbol.for()函數要接受一個字符串作爲參數,先搜索有沒有以該參數作爲名稱的Symbol值,如果有,就直接返回這個Symbol值,否則就新建並返回一個以該字符串爲名稱的Symbol值。上面代碼中,s7和s8實際上就是同一個Symbol值,所以兩者是相等的。
Symbol.keyFor()函數是用來查找一個Symbol值的登記信息的,Symbol()寫法沒有登記機制,所以返回undefined;而Symbol.for()函數會將生成的Symbol值登記在全局環境中,所以Symbol.keyFor()函數可以查找到用Symbol.for()函數生成的Symbol值。

 


 

 

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章