理解ES6中的Symbol (understanding es6 第5章)
2018-03-06 19:28
387 查看
英文电子书点此阅读《understanding es6》
目录
symbol 和 symbol属性
创建symbols
使用Symbols
共享Symbols
Symbol Coercion 类型强制转换
检索对象的symbol
用 well-known Symbols 暴露内部操作(似乎没什么用)
summary
由于它属于基本变量,也不能 new 一个 。
Symbol 函数可以接受一个可选的参数作为其描述。这个描述不能用于获取对象的属性,只是debug有用。
Symbol.for()接收一个参数,作为该symbol的字符标识符,同时也是symbol的描述
Symbol Coercion 类型强制转换
symbol 不能被随意转换为string/number。除非显式转换。
symbol 被转为 布尔型数据时, 都是true
检索对象的symbol
之前的 Object.keys()/Object.getOwnPropertyNames() 都拿到不到symbol
ES6新加了 Object.getOwnPropertySymbols()方法来以数组的方式收集对象的自有symbols
用 well-known Symbols 暴露内部操作(似乎没什么用)
这些 well-known Symbols 的 descriptor 就是类似 “Symbol.hasInstance” 这样的,同时也被定义在了 Global 的 Symbol 体系上。
Symbol.hasInstance 定义在 Fuction.prototype 上
也可以改写该函数,但必须用Object.defineProperty() 方法
4000
后面的东西太细节了,用的时候去看api吧。
放点代码:
判断是否是原生的json:
虽然不是特别私有,但Symbol类型的 属性 更不容易被错误地删改
不能用 Object.keys() 或 Object.getOwnPropertyNames() 来获取symbol 属性,但可以用Object.getOwnPropertySymbols() 来检索symbol属性。
可以改写特殊的 well-known symbols,来自定义方法。
目录
symbol 和 symbol属性
创建symbols
使用Symbols
共享Symbols
Symbol Coercion 类型强制转换
检索对象的symbol
用 well-known Symbols 暴露内部操作(似乎没什么用)
summary
symbol 和 symbol属性
一开始出于对象属性的私有性的考虑,在基础数据类型中添加了symbol(string, number, boolean, null, undefined)。但后来真正改变的只是key值不再仅仅是字符串了,私有性的初衷被放弃了。创建symbols
symbol 没有字面量的形式。要用全局的 Symbol() 函数来创建。由于它属于基本变量,也不能 new 一个 。
Symbol 函数可以接受一个可选的参数作为其描述。这个描述不能用于获取对象的属性,只是debug有用。
let firstName = Symbol() let secondName = Symbol('lala') let person = {} person[secondName] = 'wuwuwuwu'
使用Symbols
用法同computed property namelet firstName = Symbol("first name"); // use a computed object literal property let person = { [firstName]: "Nicholas" }; // make the property read only Object.defineProperty(person, firstName, { writable: false });
共享Symbols
如果想要创建一个共享的symbol,用 Symbol.for() 方法,而不是 Symbol() 方法Symbol.for()接收一个参数,作为该symbol的字符标识符,同时也是symbol的描述
// 首先它会全局搜索是否有这样一个key 叫 "uid" 的 symbol, 如果有就返回这个symbol。 // 如果没有,会创建一个新的symbol,并且注册到全局的symbol 体系中。并返回这个新symbol。 let uid = Symbol('uid') let object = {} object[uid] = 12345 console.log(object[uid]); // 12345 console.log(uid); // "Symbol(uid)" let uid2 = Symbol.for("uid"); console.log(uid === uid2); // true Symbol.keyFor(uid2); // "uid" //如果不用 Symbol.for来创建symbol, 那全局的symbol中就没有它,用keyfor寻找会找不到。
Symbol Coercion 类型强制转换
symbol 不能被随意转换为string/number。除非显式转换。
symbol 被转为 布尔型数据时, 都是true
var uid = Symbol.for('uid') var des = String(uid) //"Symbol(uid)" des = uid + '' //VM1517:1 Uncaught TypeError: Cannot convert a Symbol value to a string des = +uid //VM1520:1 Uncaught TypeError: Cannot convert a Symbol value to a number
检索对象的symbol
之前的 Object.keys()/Object.getOwnPropertyNames() 都拿到不到symbol
ES6新加了 Object.getOwnPropertySymbols()方法来以数组的方式收集对象的自有symbols
let uid = Symbol.for("uid"); let object = { [uid]: "12345" }; let symbols = Object.getOwnPropertySymbols(object);
用 well-known Symbols 暴露内部操作(似乎没什么用)
这些 well-known Symbols 的 descriptor 就是类似 “Symbol.hasInstance” 这样的,同时也被定义在了 Global 的 Symbol 体系上。
Symbol.hasInstance 定义在 Fuction.prototype 上
Object.getOwnPropertySymbols(Function.prototype) //[Symbol(Symbol.hasInstance)] obj instanceof Array // 就等于 用 Array 的 symbol 属性来取得其值 Array[Symbol.hasInstance](obj)
也可以改写该函数,但必须用Object.defineProperty() 方法
function SpecialNumber() { // empty } Object.defineProperty(SpecialNumber, Symbol.hasInstance, { value: function(v) { return (v instanceof Number) && (v >=1 && v <= 100); } }); let two = new Number(2), zero = 0; console.log(two instanceof SpecialNumber); // true console.log(zero instanceof SpecialNumber); // false 注意instanceof 的左侧必须是一个显式声明的对象,从而来调用instanceof,因为非对象只会简单地返回一个 false
4000
后面的东西太细节了,用的时候去看api吧。
放点代码:
// effectively equivalent to /^.{10}$/ let hasLengthOf10 = { [Symbol.match]: function(value) { return value.length === 10 ? [value] : null; }, [Symbol.replace]: function(value, replacement) { return value.length === 10 ? replacement : value; }, [Symbol.search]: function(value) { return value.length === 10 ? 0 : -1; }, [Symbol.split]: function(value) { return value.length === 10 ? ["", ""] : [value]; } }; let message1 = "Hello world", // 11 characters message2 = "Hello John"; // 10 characters let match1 = message1.match(hasLengthOf10), match2 = message2.match(hasLengthOf10); console.log(match1); // null console.log(match2); // ["Hello John"] let replace1 = message1.replace(hasLengthOf10, "Howdy!"), replace2 = message2.replace(hasLengthOf10, "Howdy!"); console.log(replace1); // "Hello world" console.log(replace2); // "Howdy!" let search1 = message1.search(hasLengthOf10), search2 = message2.search(hasLengthOf10); console.log(search1); // -1 console.log(search2); // 0 let split1 = message1.split(hasLengthOf10), split2 = message2.split(hasLengthOf10); console.log(split1); // ["Hello world"] console.log(split2); // ["", ""] function Temperature(degrees) { this.degrees = degrees; } // hint 是被JS引擎自动赋给的 Temperature.prototype[Symbol.toPrimitive] = function(hint) { switch (hint) { case "string": return this.degrees + "\u00b0"; // degrees symbol case "number": return this.degrees; case "default": return this.degrees + " degrees"; } }; let freezing = new Temperature(32); console.log(freezing + "!"); // "32 degrees!" console.log(freezing / 2); // 16 console.log(String(freezing)); // "32°"
判断是否是原生的json:
function supportsNativeJSON() { return typeof JSON !== "undefined" && Object.prototype.toString.call(JSON) === "[object JSON]"; }
function Person(name) { this.name = name; } Person.prototype[Symbol.toStringTag] = "Person"; let me = new Person("Nicholas"); console.log(me.toString()); // "[object Person]" console.log(Object.prototype.toString.call(me)); // "[object Person]"
summary
Symbols 是ES6新加的基本数据类型,只有用Symbol() 才能创建虽然不是特别私有,但Symbol类型的 属性 更不容易被错误地删改
不能用 Object.keys() 或 Object.getOwnPropertyNames() 来获取symbol 属性,但可以用Object.getOwnPropertySymbols() 来检索symbol属性。
可以改写特殊的 well-known symbols,来自定义方法。
相关文章推荐
- Unknown symbol gpio_direction_output
- 《iPhone开发基础教程》第5章 自动旋转和自动调整大小
- error LNK2001: unresolved external symbol _main解决办法
- VS2010中的 symbol not found 问题
- VC6调用VC2005编译生成的lib/dll库出现“unresolved external symbol "__declspec(dllimport) int __cdecl”错误的原因
- 第5章简介
- 谈EXPORT_SYMBOL使用
- 第5章 php高级编程-面向对象程序设计-郑阿奇
- vc中error LNK2001:unresolved external symbol _WinMain@16的解决方法
- Linux中EXPORT_SYMBOL的用法
- 第5章 快速生成树配置
- symbol的作用
- error LNK2019:unresolved external symbol *** referenced in function ***的解决方案
- C#与NET实战 第5章 进程、线程与同步 节选
- unresolved external symbol __endthreadex错误解决
- FC14下错误 /usr/bin/ld: libvalhalla-test.o: undefined reference to symbol 'clock_gettime@@GLIBC_2.2'
- spbase.lib(ssl3.obj) : error LNK2001: unresolved external symbol _g_fAllowInsecureRenegoClients 问题?
- error LNK2001: unresolved external symbol __imp
- vs2008 error LNK2001: unresolved external symbol __imp 多半是引入第三方库时没有定义好某些预定义
- 如何加载无法加载的symbol