潍坊市房屋和城乡建设局网站,网站建设公司itcask,做图模板网站,php网站编程Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值#xff0c; 通过Symbol函数生成 Symbol前面不能加new ,创建symbol类型指的时候传入一个参数#xff0c;这个参数需要是字符串 使用Symbol函数创建一个symbol类型值#xff0c;可以给它传入一个字符串参数#xf… Symbol是ES6新增的一种基本数据类型 它用来表示独一无二的值 通过Symbol函数生成 Symbol前面不能加new ,创建symbol类型指的时候传入一个参数这个参数需要是字符串 使用Symbol函数创建一个symbol类型值可以给它传入一个字符串参数来对symbol值所一个区分但是即使多次Symbol函数调用,传入的是相同的字符串创建的symbol值也是彼此不同的 var s Symbol(keke)
可转为string或布尔类型的值
s.toString()//Symbol(keke)
Boolean(s)//true可作为属性名
var s Symbol()
console.log(s);
let obj {[s]:kekek
}
console.log(obj); //{Symbol(): kekek}
console.log(obj[s]);//keke访问到Symbol类型的属性名
var s Symbol(name)
let obj {[s]: kke,age: 12
}
for(var key in obj){console.log(key);//age
}
console.log(Object.keys(obj));//[age]
console.log(Object.getOwnPropertyNames(obj)); //[age]
console.log(JSON.stringify(obj)); //{age:12}虽然这么多方法都无法遍历访问到Symbol类型的属性名但是Symbol类型的属性并不是私有属性我们可以使用
Object.getOwnPropertySymbols方法获取对象的所有symbol类型的属性名
let SymbolProNames Object.getOwnPropertySymbols(obj)
console.log(SymbolProNames);//[Symbol(name)]可取到Symbol属性名对应的值
console.log(obj[SymbolProNames[0]]); //kk除了Object.getOwnPropertySymbols这个方法还可以用ES6提供的Reflect对象的静态方法 Reflect.ownKeys,它可以返回所有类型的属性名所以Symbol类型的也会返回
console.log(Reflect.ownKeys(obj));//[age, Symbol(name)]Symbol.for()和Symbol.keyFor()
Symbol包含两个静态方法 for和keyFor
const s1 Symbol(pp)
const s2 Symbol(pp)
const s3 Symbol.for(pp)
const s4 Symbol.for(pp)
s1s2//false
console.log(s3s4)//true
console.log(s1s3);//false直接使用Symbol方法即便传入的字符串是一样的创建的symbol值也是互不相等的而使用Symbol.for方法传入字符串会先检查有没有使用该字符串调用Symbol.for方法创建的symbol值如果有直接返回该值如果没有则使用该字符串创建一个。使用该方法创建symbol值后会在全局范围内进行注册。注意这个注册的范围包括当前页面和页面中包含的iframe以及service sorker
const iframe document.createElement(iframe)
iframe.src String(window.location)
document.body.appendChild(iframe)
iframe.contentWindow.Symbol.for(lison) Symbol.for(lison) //true上面的这段意思是 创建一个iframe节点并把它放到body中我们通过这个iframe对象的contentWindow拿到这个iframe的window对象 在iframe.contentWindow上添加一个值就相当于你在当前页面定义一个全局变量一样
Symbol.keyFor() 该方法传入一个symbol值返回该值在全局注册的键名:
const sym Symbol.for(ook)
console.log(Symbol.keyFor(sym));//ook11个内置symbol值
Symbol.hasInstance
对象的Symbol.hasInstance 指向一个内部方法 当你给一个对象设置以Symbol.hasInstance为属性名的方法后, 当其他对象使用instanceof 判断是否为这个对象的实例时会调用你定义的这个方法 参数是其他的这个对象
const obj {[Symbol.hasInstance](otherObj){console.log(otherObj); //{a: a}}
}
console.log({a:a} instanceof obj)//false
instanceof 运算符用于该对象的prototype属性是否出现在某个实例对象的原型链上注意: 在TypeScript中这会报错 instanceof表达式的右侧必须属于类型 “any”,或属于分配给 Function接口类型的类型是要求你instanceof操作符右侧的值只能是构造函数或者类 或者类型any类型 这里你可以使用类型断言 将obj改为obj as any
Symbol.isConcatSpreadable
这个值是一个可读写布尔值当一个数组的Symbol.isConcatSpreadable设置为false时这个数组在数组的concat方法中不会被扁平化。
let arr [1,2,3]
console.log([].concat(arr,[4,5]));
let arr1 [a,b]
console.log(arr1[Symbol.isConcatSpreadable]);//undefined
arr1[Symbol.isConcatSpreadable] false
console.log(arr1[Symbol.isConcatSpreadable]);//false
console.log([].concat(arr1,arr));// [ [a, b, Symbol(Symbol.isConcatSpreadable): false], 1, 2,3 ]因为我们设置了Symbol.isConcatSpreadable为false所以第一个数组没有被扁平化第一个数组中的 Symbol(Symbol.isConcatSpreadable): false 不是他的元素 而是他的属性 因为数组也是对象所以也可以给数组设置属性
arr.props value
console.log(arr);//[1, 2, 3, props: value]Symbol.species
使用class定义一个类C, 使用extends继承原生构造函数Array,那么类C创建的实例就能继承所有Array原型对象上的方法比如map,filter
class C extends Array{getName(){return Ok}
}
const c new C(1,2,3)
console.log(c);//[1, 2, 3]
const a c.map(itemitem 1)
console.log(a);//[2, 3, 4]
console.log(a instanceof C);//true
console.log(a instanceof Array);//true
console.log(a.getName());//Ok这个例子中 a是由c通过map方法衍生出来的我们也看到了 a既是C的实例 也是Array的实例但是如果只想衍生出的数组是Array的实例 就需要用Symbol.species
class C extends Array{static get[Symbol.species](){return Array}getName(){return pp}
}
const c new C(1,2,3)
const a c.map(itemitem 1)
console.log(a);//[2, 3, 4]
console.log(a instanceof C);//false
console.log(a instanceof Array);//true
console.log(a.getName());//error a.getName is not a function就是给类C定义一个静态get存取器方法方法名为Symbol.species,然后再这个方法中返回要构造衍生数组的构造函数 所以最后我们看到 a instanceof c 为false 也就是a不再是c的实例 也就无法调用继承自C的方法
Symbol.match、 Symbol.search、Symbol.replace、和Symbol.split
这个Symbol.match值指向一个内部方法 当字符串Str 调用match方法时 会调用这个方法 match() 方法检索返回一个字符串匹配正则表达式的结果
let obj {[Symbol.match](string){return string.length}
}
console.log(abcds.match(obj));//5同样的还有Symbol.replace 、 Symbol.search,使用方法和Symbol.match是一样的
Symbol.iterator
数组的Symbol.iterator属性指向该数组的默认遍历器方法
const arr [1,2,3]
const interator arr[Symbol.iterator]()
console.log(interator);
console.log(interator.next());//{value: 1, done: false}
console.log(interator.next());//{value: 2, done: false}
console.log(interator.next());//{value: 3, done: false}这个Symbol.iterator方法是可写的我们可以自定义遍历器方法
Symbol.toPrimitive
对象的这个属性指向一个方法当这个对象被转为原始类型值时会调用这个方法这个对象只有一个参数 是这个对象被转为的类型
let obj {[Symbol.toPrimitive](type){console.log(type);}
}
const b obj //number
const a abc${obj} //stringSymbol.toStringTag
Symbol.toStringTag和Symbol.toPrimitive相似 对象的这个属性的值可以是一个字符串也可以是一个存取器get方法 当在对象上调用toString方法时会调用这个方法返回值将作为[object xxx] 中的xxx这个值 let obj {[Symbol.toStringTag]:kkk}
console.log(obj.toString());//[object kkk]Symbol.unscopables
这个值和with命令相关 我们先来看with怎么使用 const obj {a:a,b:b}
with(obj){console.log(a);//aconsole.log(b);//b
}可以看到 使用with传入一个对象后 在代码块中访问对象的属性就不需要写对象了直接使用它的属性 对象的Symbol.unscopables 属性指向一个对象该对象包含了当使用with关键字时哪些属性被with环境过滤掉
console.log(Array.prototype[Symbol.unscopables]);
{copyWithin: trueentries: truefill: truefind: truefindIndex: trueincludes: truekeys: truevalues: true
}在Ts中使用Symbol类型
let sym:symbol Symbol()unique symbol
ts在2.7版本对Symbol做了补充增加了 unique symbol这种类型 他是symbol的子类型 这种类型的值只能由Symbol()活Symbol.for()创建 或者通过指定类型来指定一个值是这种类型 这种类型的值仅可用于常量的定义和用于属性名。另外定义unique symbol类型的值 必须用const 不能let
const key1:unique symbol Symbol()
let key2:symbol Symbol()
let obj{[key1]:value1,[key2]:value2
}
console.log(obj[key1]);
console.log(obj[key2]);//error类型symbol不能作为索引类型使用