摘要:基本類型是一種解決命名沖突的工具。這樣,就有了個基本類型和個復雜類型使用需要注意以下幾點和一樣不具有構造函數,不能用調用。判斷對象是否某個構造函數的實例,運算符會調用它是一個數組對象屬性。即,當存在時,以此為構造函數構建對象。
Symbol基本類型
Symbol 是一種解決命名沖突的工具。試想我們以前定義一個對象方法的時候總是要檢查是否已存在同名變量:
if(String && String.prototype && String.prototype.getCodeWith){ String.prototype.getCodeWith = function(){}; }
可是這樣寫,即便已存在同名方法,但他們實現的功能不一定一樣,而且函數的接口也不一定適合自己。這樣我們就不得不再給自己的函數起個其他的名字,可以萬一又存在呢?
于是引入了 Symol,用來產生一個全局唯一的標識符,你可以放心的使用它。
它接受一個字符串參數,作為該標識符的描述:
var sym = Symbol("Discription"); var temp = Symbol("Discription"); console.log(sym); //Symbol(Discription) console.log(sym.valueOf()); //Symbol(Discription) console.log(sym.toString()); //"Symbol(Discription)" console.log(sym == temp); //false
描述符是用來幫助開發人員區別不同是 symbol,不具備其他意義, 所以 symbol 值只有toString()和valueOf() 方法。
Symbol 作為一個基本類型存在于 js 中。這樣,js 就有了6個基本類型: null, undefined, Boolean, Number, String, Symbol 和1個復雜類型: Object
使用 Symbol 需要注意以下幾點:
Symbol 和 null, undefined 一樣不具有構造函數,不能用 new 調用。
Symbol 值不能轉為數字,所以不能參與任何算術,邏輯運算
Symbol 雖然有 toString() 但 toString 得到的不是字符串,所以不能用于字符串鏈接,不能用于模板字符串
Symbol 可以轉換為 Boolean, 用在條件語句中,但所有 Symbol 都是邏輯 true
Symbol 作為屬性名時,該屬性是公開的,不是私有的
Symbol用作屬性名這個應該不陌生了,和普通標識符用法類似,只是不能使用.訪問和定義,必須使用[]:
var sym = Symbol("abc"); var fun = Symbol("getSym"); var a = {}; a[sym] = 1; var b = { [sym]: 1, [fun](){ console.log(this[sym]); } }; var c = Object.defineProperty({}, sym, {value: 1}); a[sym]; //1 b[sym]; //1 c[sym]; //1 b[fun](); //1
當然也可以定義一些常量,就像英語中 Symbol 代表一種象征,一個符號:
var log = { DEBUG: Symbol("debug"), ERROR: Symbol("error"), WARNING: Symbol("warning"), }
需要注意,Symbol 屬性只有Object.getOwnPropertySymbols(obj) 和 Reflect.ownKey(obj) 可以遍歷到:
Object.getOwnPropertySymbols(obj): 返回自身所有 Symbol 屬性名的數組,包括不可枚舉屬性
Reflect.ownKey(obj): 返回自身所有屬性名數組,包括不可枚舉屬性和 Symbol 屬性名
var sym = Symbol("pro"); var o = { a: 1, b: 2, [sym]: 3 } Object.getOwnPropertySymbols(o); //[Symbol(pro)] Reflect.ownKeys(o); //["a", "b", Symbol(pro)]
我們可以利用這個方法,構造一些非私有的內部變量:
var size = Symbol("size"); class Collection{ constructor(){ this[size] = 0; } add(num){ this[this[size]] = item; this[size]++; } static sizeOf(instance){ return instance[size]; } } var x = new Collection(); console.log(Collection.sizeOf(x)); //0 x.add("foo"); console.log(Collection.sizeOf(x)); //1 console.log(Object.keys(x)); //["0"] console.log(Object.getOwnPropertyNames(x)); //["0"] console.log(Object.getOwnPropertySymbols(x)); //[Symbol(size)]Symbol的靜態方法
Symbol.for("string"): 登記并重用一個 symbol 值
Symbol.for("aa") === Symbol.for("aa"); //true Symbol("aa") === Symbol("aa"); //false
Symbol.keyFor(symbol): 返回一個已登記的 Symbol 描述, 未登記的 Symbol 返回 undefined
var s1 = Symbol.for("aa"); var s2 = Symbol("aa"); Symbol.keyFor(s1); //"aa" Symbol.keyFor(s2); //undefined
注意 Symbol 的登記是全局的:
iframe = document.createElement("iframe"); iframe.src = String(window.location); document.body.appendChild(iframe); iframe.contentWindow.Symbol.for("aa") === Symbol.for("aa"); //true內置的 Symbol 值
ES6 提供了12個內置的 Symbol 值,這12個值,都是對象的,且都不可枚舉、不可配置、不可修改。因為它們具有其特殊意義:
Symbol.hasInstance: 指向一個內部方法。判斷對象是否某個構造函數的實例,instanceof 運算符會調用它
Symbol.isConcatSpreadable: 是一個數組對象屬性。如果為 false 該屬性在 concat 過程不會被展開。數組對象該屬性默認值為 true, 類數組對象該屬性默認值為 false
var arr = [3,4]; [1,2].concat(arr); //[1,2,3,4] arr[Symbol.isConcatSpreadable] = false; [1,2].concat(arr); //[1,2,[3,4]]
對于一個類而言,該屬性必須返回 boolean 類型
class A1 extends Array{ [Symbol.isConcatSpreadable](){ return true; } } class A2 extends Array{ [Symbol.isConcatSpreadable](){ return false; } } let a1 = new A1(); a1[0] = 3; a1[1] = 4; let a2 = new A2(); a2[0] = 5; a2[1] = 6; [1,2].concat(a1).concat(a2); //[1, 2, 3, 4, 5, 6]
Symbol.species: 指向一個方法。將對象作為構造函數調用時,系統內部會調用這個方法。即,當 this.constructor[Symbol.species]存在時,以此為構造函數構建對象。
Symbol.match: 指向一個函數。當執行 str.match(obj) 的時候, 如果 obj 存在該屬性,調用該方法并返回該方法的返回值
String.prototype.match(searchValue); //相當于 SearchValue[Symbol.match](this); //實例 class myMatch{ constructor(str){ this.content = str; } [Symbol.match](str){ return this.content.indexOf(str); } } "e".match(new myMatch("Hello")); //1
Symbol.replace: 指向一個函數。和上一個方法類似的,當執行 str.replace(obj,replaceValue) 的時候, 如果 obj 存在該屬性,調用該方法并返回該方法的返回值
String.prototype.replace(searchValue, replaceValue); //相當于 SearchValue[Symbol.replace](this, replaceValue);
Symbol.search: 指向一個函數。和上一個方法類似的,當執行 str.search(obj) 的時候, 如果 obj 存在該屬性,調用該方法并返回該方法的返回值
String.prototype.search(searchValue); //相當于 SearchValue[Symbol.search](this);
Symbol.split: 指向一個函數。和上一個方法類似的,當執行 str.split(obj,limit) 的時候, 如果 obj 存在該屬性,調用該方法并返回該方法的返回值
String.prototype.split(seperator,limit); //相當于 seperator[Symbol.split](this,limit);
Symbol.iterator: 指向默認的遍歷器方法。對象在 for...of 中默認調用該方法。
class Collector{ constructor(...vals){ this.nums = vals; } *[Symbol.iterator](){ let i = this.nums.length; while(i){ i--; yield this.nums[i]; } } } var collector = new Collector(1,2,3,4,5); for(let value of collector){ console.log(value); //依次輸出 5 4 3 2 1 }
Symbol.toPrimitive: 指向一個方法。對象被轉為原始類型值時會調用該方法。該方法介紹一個字符串參數,可選參數:
"number": 此時轉換成數值,應返回數值類型
"string": 此時轉換成字符串,應返回字符串類型
"default": 此時轉換成數值或字符串,應返回數值或字符串類型
var obj = { [Symbol.toPrimitive](hint){ switch(hint){ case "number": return 1234; case "string": return "hello"; case "default": return "default"; default: throw new Error(); } } }; console.log(obj.toString()); //[object Object] console.log(obj.valueOf()); //{ console.log(2 * obj); //2468 console.log(2 + obj); //2default console.log(obj === "hello"); //false console.log(String(obj)); //hello
Symbol.unscopables: 該讀取器指向一個對象。指定了在使用 with語句 時,那些屬性被 with 環境排除(無法訪問)
//例1 console.log(Array.prototype[Symbol.unscopables]); //輸出如下,數組對象在 with 中不能訪問這些屬性方法 //{ //copyWithin: true, //entries: true, //fill: true, //find: true, //findIndex: true, //includes: true, //keys: true //}
//例2 //沒有 unscopables 時 class MyClass{ foo(){return 1} } var foo = () => 2; with(MyClass.prototype){ foo(); //1 } //有 unscopable 時 var foo = () => 2; class MyClass{ foo(){return 1;} get [Symbol.unscopables](){ return {foo:true}; } } with(MyClass.prototype){ foo(); //2 }
Symbol.toStringTag: 指向一個方法。該方法指向函數名是對象 toString 返回值 [object Array] 中 Array 部分。
var b = { [Symbol.toStringTag]:"Hello" }; console.log(b.toString()); //"[object Hello]"
ES6 新增的 Symbol.toStringTag 如下:
JSON["Symbol.toStringTag"]: "JSON"
Math["Symbol.toStringTag"]: "Math"
Module對象 M["Symbol.toStringTag"]: "Module"
ArrayBuffer.prototype["Symbol.toStringTag"]: "ArrayBuffer"
DataView.prototype["Symbol.toStringTag"]: "DataView"
Map.prototype["Symbol.toStringTag"]: "Map"
Promise.prototype["Symbol.toStringTag"]: "Promise"
Set.prototype["Symbol.toStringTag"]: "Set"
%TypedArray%.prototype["Symbol.toStringTag"]: "Uint8Array"等9種
WeakMap.prototype["Symbol.toStringTag"]: "WeakMap"
WeakSet.prototype["Symbol.toStringTag"]: "WeakSet"
%MapIteratorPrototype%["Symbol.toStringTag"]: "Map Iterator"
%SetIteratorPrototype%["Symbol.toStringTag"]: "Set Iterator"
%StringIteratorPrototype%["Symbol.toStringTag"]: "String Iterator"
Symbol.prototype["Symbol.toStringTag"]: "Symbol"
Generator.prototype["Symbol.toStringTag"]: "Generator"
GeneratorFunction.prototype["Symbol.toStringTag"]: "GeneratorFunction"
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97447.html
摘要:一簡介與的關系是的規格,是的一種實現另外的方言還有和轉碼器命令行環境安裝直接運行代碼命令將轉換成命令瀏覽器環境加入,代碼用環境安裝,,根目錄建立文件加載為的一個鉤子設置完文件后,在應用入口加入若有使用,等全局對象及上方法安裝 一、ECMAScript6 簡介 (1) 與JavaScript的關系 ES是JS的規格,JS是ES的一種實現(另外的ECMAScript方言還有Jscript和...
摘要:筆記和和是塊作用域的,是聲明常量用的。一個對象如果要有可被循環調用的接口,就必須在的屬性上部署遍歷器生成方法原型鏈上的對象具有該方法也可。這種方式會訪問注冊表,其中存儲了已經存在的一系列。這種方式與通過定義的獨立不同,注冊表中的是共享的。 ECMAScript6 筆記 let 和 const let和const是塊作用域的 ,const是聲明常量用的。 {let a = 10;} a ...
基本擴展 允許使用已有對象賦值定義對象字面量,并且只寫變量名即可 var name = Bob; var getName = function(){console.log(this.name);}; var person = {name, getName}; //相當于 //var person = { //name: Bob, //getName: function(){console.log...
摘要:屬性的簡潔表示法允許直接寫入變量和函數作為對象的屬性和方法。,中有返回一個數組,成員是參數對象自身的不含繼承的所有可遍歷屬性的鍵名。對象的擴展運算符目前,有一個提案,將解構賦值擴展運算符引入對象。 1 屬性的簡潔表示法 ES6允許直接寫入變量和函數作為對象的屬性和方法。 寫入屬性 var name = value; var obj = { name }; console.log...
摘要:由于中引入了許多數據結構算上原有的包括等等數組需要一個東西來管理他們這就是遍歷器。數組默認遍歷器遍歷值相當于依次輸出依次輸出依次輸出依次輸出不難看出默認得到值而只能得到索引。即遍歷器的本質就是一個指針。 由于 ES6 中引入了許多數據結構, 算上原有的包括Object, Array, TypedArray, DataView, buffer, Map, WeakMap, Set, We...
閱讀 819·2021-10-25 09:48
閱讀 611·2021-08-23 09:45
閱讀 2496·2019-08-30 15:53
閱讀 1759·2019-08-30 12:45
閱讀 586·2019-08-29 17:21
閱讀 3407·2019-08-27 10:56
閱讀 2547·2019-08-26 13:48
閱讀 691·2019-08-26 12:24