ES6的出現,我個人認爲,對js的發展會起到很大的作用。對前端的一些功能實現也起到了很大幫助。
我們都知道es5 爲我們提供了六種數據類型。分別是: 對象(Object)、數字類型(Number) 、布爾類型(Boolean)、字符串類型(String)、空類型(Null)、未定義類型(Undefind)
E6又爲我們增加了一種類型 symbol 類型,他表示獨一無二的值。這樣下來js 就有七種數據類型了。
一、symbol 用法
1.symbol 的用法很簡單:
let a = Symbol();
console.log(a); // symbol()
console.log(typeof a) // 它的類型就是 symbol
// 我們也可以爲symbol 類型加一些參數(做一些標記號) 用來區分
let b = Symbol("b")
console.log(b) // symbol(b)
因爲symbol類型 表示的是獨一無二的值,所以
即便變量都是symbol類型,那麼也不相等。
var a = Symbol();
var b = Symbol();
console.log(a == b) // fales
2.symbol數據注意點
① symbol 數據類型不能夠轉換爲數值類型,否則會報錯
② symbol 數據類型不能用new 操作符去聲明,因爲它本身是一個原始值,而不是對象
③ symbol 數據類型不能夠和字符串進行拼接,否則會報錯
④ symbol 數據類型可以轉化爲布爾類型
二、Symbol 的用途
ES6 新增一個這個數據類型有什麼用處呢。首先我們它解決了我們在定義一個對象時,不小心把鍵改寫或覆蓋的問題。
1.作爲屬性名
var obj = {
username:"jhon",
age:23,
sex:"man",
username:"king"
}
console.log(obj.name) // king
上邊 由於name 又一次出行將之前的name 值給覆蓋了,你可能認爲這種錯誤基本不能出現,但是如果但你處理的數據比較多時,這種錯誤出現的概率還是很大的。
我們這樣寫:
var username = Symbol();
var obj = {
[username]: 'Jhone',
age:23,
sex:"man",
}
console.log(obj[username]) // hello
上邊需要注意的是:
①usename 定義爲symbol 類型後,如果在出現 username 的鍵 將會報錯。
② 因爲username 是變量,變量作爲屬性要用[]
中括號,如果使用.
默認會將屬性變爲字符串。
重點內容
③ 上邊的 username 如果變成 name = Symbol()
將會報錯Cannot convert a Symbol value to a string
不能將一個符號值轉換爲字符串 ,這裏報這個錯誤我不是很明白,name 應該不會是關鍵詞。如果有知道的,歡迎留言。
給對象填屬相我們還可以用defineProperty()
var obj={};
Object.defineProperty(obj,username,{value:"Jhone"});
2.消除魔術變量
魔術字符串指的是,在代碼之中多次出現、與代碼形成強耦合的某一個具體的字符串或者數值。風格良好的代碼,我們應該儘量消除魔術字符串。(這裏我引用的是阮一峯的例子)
function getArea(shape, options) {
var area = 0;
switch (shape) {
case 'Triangle': // 魔術字符串
console.log(1);
break;
/* ... more code ... */
}
return area;
}
getArea('Triangle', { width: 100, height: 100 }); // 魔術字符串
上面的代碼,字符串triangle 就是一個魔術字符串,它多次出現,與代碼形成“強耦合”,不利於將來的修改和維護。
常用的消除魔術字符串的方法,就是把它寫成一個變量:
var shapeType = {
triangle: 'Triangle'
};
function getArea(shape, options) {
var area = 0;
switch (shape) {
case shapeType.triangle:
console.log(1);
break;
}
return area;
}
getArea(shapeType.triangle, { width: 100, height: 100 });
上面代碼中,我們把Triangle寫成shapeType對象的triangle屬性,這樣就消除了強耦合。
如果仔細分析,可以發現shapeType.triangle等於哪個值並不重要,只要確保不會跟其他shapeType屬性的值衝突即可。因此,這裏就很適合改用 Symbol 值。
const shapeType = {
triangle: Symbol()
};
上面代碼中,除了將shapeType.triangle的值設爲一個Symbol,其他地方都不用修改。
三、symbol 的一些方法
1.當symbol 作爲屬性名時,改屬性不會被for....in
、 for...of
遍歷, 也不會被Object.keys()
、 Object.getOwnPropertyNmaes()
、JSON.stringify()
返回
但是它也不是一個私有屬性,它有以下方法:
① Object.getOwnPropertySymbols()
方法返回一個數組,成員是當前對象的所有用作屬性名的Symbol 值。
var a = Symbol("a");
var b = Symbol("b");
var c = Symbol("c");
obj = {
[a]:"a",
[b]:'b',
[c]:'c'
}
console.log( Object.getOwnPropertySymbols(obj)) //[Symbol(a), Symbol(b), Symbol(c)]
② Symbol.for() 方法
有時候,我們希望重新使用同一個Symbol 值。而symbol.for
方法可以做到。
具體實現:它接收一個字符串作爲參數,然後搜索有沒有以該參數作爲名稱的symbol 值,如果有,返回這個值,否則就新建並返回一個以該字符串爲名稱 的Symbol 值。
var a = Symbol.for('one');
var b = Symbol.for('one');
console.log(a === b) // true
③ Symbol.keyFor() 方法
返回一個已登記的Symbol 類型的key值
例如:
var a = Symbol.for('one');
var c = Symbol("two");
console.log(Symbol.keyFor(a)); // one
console.log(Symbol.keyFor(c)); // underfined
通過上面的例子可以看出,Symbol.keyFor()
方法返回一個登記的Symbol 類型值得 key,而直接聲明的 Symbol() 沒有。如果你Symbol.keyFor()
沒有參數,那麼也不會有key值