你一閉眼世界就黑了,你不是主角是什么?
目錄
- 什么是Symbol?
- ?Symbol特點?:
- 創建方法:
- 注意點:
- 不能進行運算:
- 顯示調用toString() --沒有意義
- 隱式轉換boolean
- 如果屬性名沖突了怎么辦?
- obj.name和obj[name]的區別:
- 變量命名:
- 避免直接寫Symbol()代替變量:
- 整合變量:
- 接受傳參:
- 不能進行for in 循環:
- Object.getOwnPropertySymbols():
- Reflect.ownKeys() 遍歷屬性名和屬性值:
- 作為常量:
什么是Symbol?
ES6引入了一種新的原始數據類型 Symbol
,表示獨一無二的值,它屬于JavaScript語言的原生數據類型之一。
其他數據類型是: Undefined
、Null
、布爾值(Boolean
)、字符串(String
)、數值(Number
)、對象(Object
)。
?Symbol特點?:
- 由于每一個Symbol值都是不相等的,這意味著Symbol值可以作為標識符,用于對象的屬性名,保證不會出現同名的屬性。
- Symbol主要用于對象屬性的唯一性標識,可以解決屬性名沖突的問題。
創建方法:
let s1 = Symbol(); // 生成了一個symbol類型的數據
console.log(typeof s1); // symbol
每次創建都會生成一個獨一無二的值:
let s1 = Symbol(); // 生成了一個symbol類型的數據
let s2 = Symbol();
console.log(s1 === s2); // false
注意點:
不能進行運算:
Symbol數據類型在JavaScript中是不能進行常規的數學運算的,包括加法(+)、減法(-)、乘法(*)、除法(/)以及比較運算(>、<、>=、<=)等。
let s1 = Symbol();
console.log(s1 + 'aaaa');// es6.html:16 Uncaught TypeError: Cannot convert a Symbol value to a string
顯示調用toString() --沒有意義
let s1 = Symbol();
console.log(s1.toString()); // Symbol()
console.log(s1.toString() + 'aaa'); // Symbol()aaa
隱式轉換boolean
let s1 = Symbol();
// 這里的s1相當于true
if (s1) {console.log('執行');
}
如果屬性名沖突了怎么辦?
obj.name和obj[name]的區別:
點擊 看 obj.name和obj[name]的區別
let obj = {name: 'sssssy',getName() {console.log(this.name);}
}let name = Symbol();
obj[name] = 'kitty'
console.log(obj);
console.log(obj.name); //sssssy
console.log(obj[name]); // kitty
變量命名:
所以寫庫的作者會盡量避免直接.xxx來進行命名:
let name = Symbol();
let age = Symbol();
let obj = {[name]: 'sssssy',[age]: 100
}
console.log(obj);
避免直接寫Symbol()代替變量:
避免變量直接寫 Symbol():
let obj = {[Symbol()]: '123', //這樣雖然可以創建一個獨一無二的值,但是訪問不了。
}
console.log(obj[Symbol()]); // undefined 因為這里類似于創建了一個新的Symbol類型。
整合變量:
如果變量過多,也可以這樣來寫:
let keys = {name: Symbol(),age: Symbol(),loacation: Symbol(),test: Symbol(),
}let obj = {[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}
console.log(obj);
console.log(obj[keys.name]); // sssssy
obj[keys.test](); // test
接受傳參:
由于展開全是Symbol(),我不知道是哪個變量,所以可以往Symbol()的括號里面添加參數【接受傳參】,讓我們能看出是哪個變量:
let keys = {name: Symbol("name"),age: Symbol("age"),loacation: Symbol("location"),test: Symbol("test"),
}let obj = {[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}
console.log(obj);
不能進行for in 循環:
let keys = {name: Symbol("name"),age: Symbol("age"),loacation: Symbol("location"),test: Symbol("test"),
}let obj = {name: '普通屬性',[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}for (let i in obj) {console.log(i);
}
只能打印出普通屬性。。。
那該怎么辦呢?
使用Object.getOwnPropertySymbols() 可以拿到所有的Symbol屬性
Object.getOwnPropertySymbols():
let keys = {name: Symbol("name"),age: Symbol("age"),loacation: Symbol("location"),test: Symbol("test"),
}let obj = {name: '普通屬性',[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}console.log(Object.getOwnPropertySymbols(obj));
跪求既能拿到普通屬性,又能拿到Symbol屬性的方法!!!
好的。。平身。。。
就是使用:Reflect.ownKeys()
let keys = {name: Symbol("name"),age: Symbol("age"),loacation: Symbol("location"),test: Symbol("test"),
}let obj = {name: '普通屬性',[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}console.log(Reflect.ownKeys(obj));
老鐵們把666打到公屏上!! 66666~6666~6666~
Reflect.ownKeys() 遍歷屬性名和屬性值:
包含所有普通屬性的和Symbol屬性的:
let keys = {name: Symbol("name"),age: Symbol("age"),loacation: Symbol("location"),test: Symbol("test"),
}let obj = {name: '普通屬性',[keys.name]: 'sssssy',[keys.age]: 18,[keys.loacation]: '北京',[keys.test]() {console.log('test');}
}Reflect.ownKeys(obj).forEach(item => {console.log(item, obj[item]);
})
作為常量:
正常調用:
function play(type) {switch (type) {case 1:console.log('視頻播放');break;case 2:console.log('音頻播放');break;case 3:console.log('圖片播放');break;}
}
play(1) // 視頻播放
play(2) // 音頻播放
play(3) // 圖片播放
1 2 3這樣數字寫的用戶不理解,我們把它們換成可理解的:
但是這樣如果我提前知道這些數字,依舊可以通過數字去調用到
const VIDEO = 1;
const AUDIO = 2;
const IMAGE = 3;
function play(type) {switch (type) {case VIDEO:console.log('視頻播放');break;case AUDIO:console.log('音頻播放');break;case IMAGE:console.log('圖片播放');break;}
}
play(VIDEO) // 視頻播放
play(1) // 視頻播放
這時候就可以使用Symbol作為一個常量:(也就是作為一種應用,統一代碼的一致性)
const VIDEO = Symbol();
const AUDIO = Symbol();
const IMAGE = Symbol();
function play(type) {switch (type) {case VIDEO:console.log('視頻播放');break;case AUDIO:console.log('音頻播放');break;case IMAGE:console.log('圖片播放');break;}
}
play(VIDEO) // 視頻播放
play(1) // 什么都沒有