木灵鱼儿
阅读:1704
Symbol
es6引入了一个新的数据类型Symbol,用于表示独一无二的值,他是JavaScript第七种数据类型。
Symbol值通过Symbol函数生成,但是不需要new,用于解决属性名容易被人复写的问题。
目前对象的属性名都是string类型,也就是字符串,现在新增了symbol类型,只要属性名是symbol类型,就是独一无二的,可以保证不会与其他属性名产生冲突。
let s = Symbol();
typeof s //"symbol"
基本使用
Symbol函数接收一个字符串参数,表示对Symbol实例的描述,主要是为了再控制台显示,而且即便两个Symbol使用同一个字符串描述,他们也是不相等的。
let s = Symbol("foo");
let a = Symbol("foo");
s === a //false
s.toString(); // "foo"
a.toString(); // "foo"
symbol可以转换为布尔值或者字符串,但是无法被转换为数值。
作为属性名的Symbol
由于每一个symbol值都是不相等的,这意味着symbol可以作为标识符用于对象的属性名,保证不会出现重名,特别是在一些一个对象有多个模块组成,有继承的情况下,能防止某一个键不会被改写或覆盖。
var my = Symbol();
//第一种写法
var a = {};
a[my] = "第一种";
//第二种
var b = {
[my]: "第二种"
}
//第三种
var c = {};
Object.difineProperty(c,my,{value:"第三种"});
//以上写法都可以
注意一点就是symbol不能使用点运算符,因为他不是string,如果使用点运算符来作为对象的属性名,会被识别为字符串
var my = Symbol();
var a = {};
a.my = "xxx";
//a.my 等于 a["my"]
所以,在作为属性名时,是需要方括号包裹的
var my = Symbol();
var a = {};
a[my] = "xxx";
var b = {
[my]: "第二种"
}
var c = {
[my]() {
//函数
}
}
属性名的遍历
symbol作为属性名,该属性不会出现在for...in、for...of
循环中,也不会被Object.keys()、Object.getOwnPropertyNames()返回,但他不是私有属性,可以通过Object.getOwnPropertysSymbols()
方法获取指定对象的所有symbol属性名
该方法返回一个数组,成员为当前对象的所有作为属性名的symbol值
var my = Symbol();
var a = {};
a[my] = "xxx";
var symbolArr = Object.getOwnPropertysSymbols(a);
symbolArr; //[Symbol()]
es6新增了一个新的apiReflect.ownKeys()
,可以返回所有类型的键名,包括常规的string和symbol,也是一个数组。
var my = Symbol();
var a = {
d: "xxx"
};
a[my] = "xxx";
var arr = Reflect.ownKeys(a);
arr; //["d",Symbol()]
symbol无法被常规方法遍历到,我们可以利用这个特性为对象定义一些非私有但是又希望只用于内部的方法。
具体暂时还不明白用法,等学了class再看看。
Symbol.for()、Symbol.keyFor()
有时,我们希望能重新使用同一个symbol值,于是有了symbol.for,使用该方法创建的symbol,他也接收一个字符串作为参数,然后他会进行全局搜索,如果全局里面没有以这个参数作为名称的symbol值,就创建一个,有的话就返回对应的已经存在的symbol
var a = Symbol.for("foo");
var b = Symbol.for("foo");
a===b; //true
但是这个相等是有前提的,是一定是for创建的,因为Symbol()
他创建的永远是唯一的,而Symbol.for()
创建的,他其实是有查询表的,类似于在全局有一张键值对的表,每次都是查询这个表,有就拿,没有就创建。
所以:
var a = Symbol.for("foo");
var b = Symbol("foo");
a===b; //false
她两是不相等的。
而Symbol.keyFor()
就是用来判断,全局的那张查询表是否存在这个已经登记的symbol
var a = Symbol.for("foo");
Symbol.keyFor(a); //"foo"
var b = Symbol("foo");
Symbol.keyFor(b); //undefined
Symbol.keyFor()
会直接返回那个已经登记的key,没有则是undefined
注意:
由于Symbol.for
创建的是全局的,所有,可以在不同的iframe或者service worker中使用同一份symbol对象
var iframe = document.createElement("iframe");
iframe.src = String(window.location);
document.body.appendChild(iframe);
iframe.contentWindow.Symbol.for("foo") === Symbol.for("foo");
//true
contentWindow
可以获取到iframe的window对象,也就是全局对象,他的全局对象Symbol使用for创建一个symbol,按道理,他应该是iframe中的,不可能和外面的Symbol.for("foo")
相等,但是由于都在同一个页面下,所以是相等的,因为symbol的登记是全局环境的。
Symbol内置值
es6里面通过一些新的属性,对原来的一些对象属性进行了调整,配合Symbol进行了调整,具体就不多说了,目前也没想到哪里需要用到,等需要了再百度吧。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
异步队列管理器
造这个轮子其实也是没得办法,搜不到合适的轮子用,就只能自己干了。使用场景我们有N个异步任务promise,他们没有顺序关系,谁先触发都无所谓,但是我们只关心一点,如果某一个任务出错,后续就不要运行了,只有全部都success完成,那么才运行成功后的处理方式then。当然,我们肯定不能使用Promise.all运行N个任务,这等于是同步触发了,如果我有2000个任务,难道你也一口气发2000个任务,那这就不现实了,所以这里我们要引入线程概念,一个进程可以有多个线程,那么进程就是管理器,线程就是我们一次可以发多少个请求。线程是可以配置的,我们可以指定触发多少个线程,当1个线程完成后,我们要填...
Iterator 和 for...of 循环
Iterator(遍历器)的概念JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了Map和Set。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。Iterator 的作用有三个:一是为各种数据结构,提供一个统一...
Promise
基本了解Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。Promise对象有以下两个特点。(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfil...
Reflect
Reflect也是es6新增的api,他的出现主要是解决以下几点问题:将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上修改Object对象的一些方法的返回结果,比如:Object.defineProperty(obj, name, desc)在无法定义属性时,会抛出一个错误,而Reflect.defineProperty(obj, name, desc)则会返回false。// 老写法 try { Object.defineProperty(target, property, attributes); //...
Proxy 代理
简介proxy用于修改某些操作的默认行为,由于是在语言层做出了修改,所以属于一种“元编程”,也可以理解为代理层,可以对外界的访问进行过滤改写。var proxy = new Proxy(target, handler);new 出Proxy,接收两个参数,一个是需要被代理的对象target,一个是代理的拦截器配置对象。var proxy = new Proxy({}, { get: function(target, propKey) { return 35; } }); proxy.time // 35 proxy.name // 35 proxy.title // 3...
Object 对象的扩展
属性的简写es6允许对属性进行简写,可以直接使用变量,变量名直接成为了属性名。var a = "hello"; var b = {a}; //等同于 var b = { a:a }属性里的方法也可以简写var a = { b(){...} } //等同于 var a = { b: function(){ ... } }在CommonJS模块输出变量时,也就是node模块导出时,这种简写就显得十分方便,我们直接导致一个对象,对象里面使用简写。var a = {}; var b = {}; module.exports = {a,b}而属性的赋...
Array 数组扩展
扩展运算符console.log(...[1,2,3]); //1,2,3扩展运算符会将后面跟着的数组转换为参数序列,这种效果一般用于函数参数,数组操作里面。扩展运算符后面甚至可以接表达式,但是表达式一定要有数组抛出const arr = [...(x>0?[1]:[]),2];如果是一个空数组使用扩展运算符,则无任何效果const a = []; console.log([...a,1]); //[1]代替数组的apply方法首先要知道apply除了改变this的指向外,第二个参数是一个数组,apply会将这个数组转为序列参数。如:function test(x,y,z){ ...

如何管理系统中使用的图标
关于图标的方案,现阶段也就三种:雪碧图字符图标svg雪碧图雪碧图就是将多个图标图片合并到一张图里面,前端通过控制图片的大小位置来进行显示。但是也有缺陷,就是图片的清晰度了,如果放大了,就会显的很模糊。字符图标字符图标是目前最成熟的一种方案,使用简单,并且是和字体一样的,放大依旧很清晰。但是他的缺点就是不支持多色图标,也就是一个字符图标,他无法同时显示多种颜色。svgsvg是最近开始兴起的,它是一种组件化封装的方式,将svg代码化,以达到控制的目的,而且相对于字符字体,svg本身有很多优势,比如动画,多色等等因为组件化了,所以我们可以按需引入,虽然字符图标也可以,但是那种是需要平台的支持,...
Function 函数
函数默认参数es5无法设置默认参数,只能通过函数内部先进行判断,如果没有参数则设置一个值。function test(x,y){ x = x || "hello "; y = y || "word"; console.log(x+y); } test(); //hello word这样写的话会有一个问题,就是如果我就要参数为空,就会出现问题test("","test"); // hello test所以我们还需要加一个判断function test(x,y){ x = typeof x...
关于es6 解构报错的一些经验
es6的解构非常好用,可以省去很多代码。为此我测试了一些场景的错误没有对应的keyconst {data} = {datas:"文本"};这种情况下,有值,但是key无法解析,那么就会返回undefined,也就是data输出是个undefined没有值const {data} =null;这种情况就会报错,这个报错会停止js的运行,所以我们需要用try--catch捕获key对应的值为nullconst {data} ={datas:null};这种情况也不会报错,他会把null拿到综合情况const {data,test} ={datas:null};这种情况并不...