摘要:创建及辨别方法是原始值,因此调用会导致程序抛出错误使用来辨别其类型可用于计算对象字面量属性名如果想创建一个共享的,可使用方法方法在全局注册表中检索与有关的键全局注册表是一个类似全局作用域的共享环境,也就是说你不能假设目前环境中存在哪些键与类
创建Symbol及辨别方法
Symbol是原始值,因此调用new Symbol会导致程序抛出错误
let firstName = Symbol() let person = {} person[firstName] = "angela" console.log(person[firstName])
使用typeof来辨别其类型
let symbol=Symbol("this is test description") console.log(typeof symbol)//symbol
Symbol可用于计算对象字面量属性名、Object.defineProperty、Object.defineProperties
如果想创建一个共享的Symbol,可使用Symbol.for方法
let uid = Symbol.for("uid") let object = { [uid]: "12345" } console.log(object[uid])//12345 console.log(uid)//Symbol(uid) let uid2 = Symbol.for("uid") console.log(uid === uid2)//true console.log(object[uid2])//12345 console.log(uid2)//Symbol(uid)
Symbol.keyFor方法在Symbol全局注册表中检索与Symbol有关的键
let uid = Symbol.for("uid") console.log(Symbol.keyFor(uid))//uid let uid2 = Symbol.for("uid") console.log(Symbol.keyFor(uid2))//uid let uid3=Symbol("uid") console.log(Symbol.keyFor(uid3))//undefined
Symbol全局注册表是一个类似全局作用域的共享环境,也就是说你不能假设目前环境中存在哪些键
Symbol与类型强制转换不能将Symbol强制转换成数字类型,Symbol也不可以被转换成字符串
let uid = Symbol.for("uid") let desc = uid + ""//报错 Uncaught TypeError: Cannot convert a Symbol value to a string
let uid = Symbol.for("uid") let desc = uid / 1//报错 Uncaught TypeError: Cannot convert a Symbol value to a number
但是却可以像下面这样使用
let uid = Symbol.for("uid") let desc = String(uid) console.log(desc)//Symbol(uid)Symbol属性检索
Object.getOwnPropertySymbols
let uid = Symbol.for("uid") let object = { [uid]: "12345" } let symbols=Object.getOwnPropertySymbols(object)Symbol.hasInstance
Symbol.hasInstance只接受一个参数,即要检查的值
每个函数都有Symbol.hasInstance方法,用于确定对象是否为函数实例,该方法在Function.prototype中定义,该方法被定义不为可写、不可配置、不可枚举
let obj = [] //obj instanceof Array //下面一句代码与此句功能等价 Array[Symbol.hasInstance](obj)//true
我们可以通过Object.defineProperty方法改写一个不可写属性
所以其实可以重写所有内建函数(如Date和Error)默认的Symbol.hasInstance属性
function SpecialNumber() { } Object.defineProperty(SpecialNumber, Symbol.hasInstance, { value: function (v) { return (v instanceof Number) && (v >= 1 && v <= 100) } }) var two = new Number(2), zero = new Number(0); console.log(two instanceof SpecialNumber)//true console.log(zero instanceof SpecialNumber)//falseSymbol.isConcatSpreadable
Symbol.isConcatSpreadable属性值为true表明属性值应当作为独立元素添加到数组中
let c1 = ["red", "green"], c2 = c1.concat(["blue", "black"], "yellow") console.log(c2)//["red", "green", "blue", "black", "yellow"]
为什么上面一段代码结果是["red", "green", "blue", "black", "yellow"]而不是["red", "green", ["blue", "black"], "yellow"]?
如果把上面的代码稍微改一下,结果就完全不一样了
let collection = { 0: "hello", 1: "world", 2: "demo", 3: "test", [Symbol.isConcatSpreadable]: true, length: 4 } let msg = ["Hi"].concat(collection) console.log(msg)//["Hi", "hello", "world", "demo", "test"]Symbol.match,Symbol.replace,Symbol.search,Symbol.split
let hasLenOf10 = { [Symbol.match](v) { return v.length === 10 ? [v.substring(0, 10)] : null }, [Symbol.replace](v, replacement) { return v.length === 10 ? replacement + v.substring(10) : v; }, [Symbol.search](v) { return v.length === 10 ? 0 : -1 }, [Symbol.split](v) { return v.length === 10 ? ["", ""] : [v] } } let msg1 = "Hello world", msg2 = "Hello John"; console.log(msg1.match(hasLenOf10))//null console.log(msg2.match(hasLenOf10))//[Hello John] console.log(msg1.replace(hasLenOf10))//Hello world console.log(msg2.replace(hasLenOf10))//undefined console.log(msg1.search(hasLenOf10))//-1 console.log(msg2.search(hasLenOf10))//0 console.log(msg1.split(hasLenOf10))//["Hello world"] console.log(msg2.split(hasLenOf10))//["",""]Symbol.toPrimitive
在执行特定操作时,经常会尝试将对象转换到相应的原始值
Symbol.toPrimitive被定义在每一个标准类型的原型上,并且规定了当对象被转换为原始值时应该执行的操作
每当执行类型转换总会调用Symbol.toPrimitive方法并传入一个值作为参数,这个值在规范中被称作类型提示hint,类型提示参数只有三种选择number、string、default
function Temperature(degree) { this.degree = degree } Temperature.prototype[Symbol.toPrimitive] = function (hint) { switch (hint) { case "string": return this.degree + "u00b0"; case "number": return this.degree; case "default": return this.degree + " degrees" } } var freezing = new Temperature(32) console.log(freezing + "!")//32 degrees! console.log(freezing / 2)//16 console.log(String(freezing))//32°Symbol.toStringTag
以前判断一个对象的类型一般都是这样
function isArray(value) { return Object.prototype.toString.call(value) === "[object Array]" }
ES6中我们可以自定义对象字符串标签
function Person(name) { this.name = name } Person.prototype[Symbol.toStringTag] = "Person" Person.prototype.toString = function () { return this.name } var me = new Person("angela") console.log(me.toString())//angela console.log(Object.prototype.toString.call(me))//[object Person]
如果我们不重写toString方法,则me.toString返回的值就是[object Person]
我们可以给Person.prototype[Symbol.toStringTag]赋任意值,当然也可以修改原生对象的字符串标签
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/87378.html
摘要:创建及辨别方法是原始值,因此调用会导致程序抛出错误使用来辨别其类型可用于计算对象字面量属性名如果想创建一个共享的,可使用方法方法在全局注册表中检索与有关的键全局注册表是一个类似全局作用域的共享环境,也就是说你不能假设目前环境中存在哪些键与类 创建Symbol及辨别方法 Symbol是原始值,因此调用new Symbol会导致程序抛出错误 let firstName = Symbol()...
摘要:什么是迭代器中创建迭代器如下所示什么是生成器生成器是一种返回迭代器的函数每当招待完一条语句后函数就会自动停止执行关键字可返回任何值或表达式关键字只可在生成器内部使用,在其它地方使用会导致程序抛出语法错误所以下面例子是有错误的可迭代对象具有属 什么是迭代器 ES5中创建迭代器如下所示: function createIterator(items) { var i = 0 retu...
摘要:什么是迭代器中创建迭代器如下所示什么是生成器生成器是一种返回迭代器的函数每当招待完一条语句后函数就会自动停止执行关键字可返回任何值或表达式关键字只可在生成器内部使用,在其它地方使用会导致程序抛出语法错误所以下面例子是有错误的可迭代对象具有属 什么是迭代器 ES5中创建迭代器如下所示: function createIterator(items) { var i = 0 retu...
阅读 773·2023-04-26 00:30
阅读 2665·2021-11-23 09:51
阅读 1029·2021-11-02 14:38
阅读 2533·2021-09-07 10:23
阅读 2213·2021-08-21 14:09
阅读 1274·2019-08-30 10:57
阅读 1592·2019-08-29 11:20
阅读 1115·2019-08-26 13:53