javascript中原始值,即基本数据类型,像Number,String,Boolean,undefined,Null都是基本类型值,保存在栈中,但是有个疑问:

Symbol打印出来明明是个函数,具有prototype的属性,不能实例化的原因是:Symbol是个原始值。但Symbol明明就是个函数的鸭,而且:

Symbol.__proto__ === Function.prototype     //true
Symbol.constructor === Function.prototype.constructor //true
Object.prototype.toString.call(Symbol) //"[object Function]"
typeof Symbol //"function"
typeof Symbol() //"symbol"

Symbol的原型指向的就是Function的原型,Symbol明明就是Function的实例鸭。

其实JS中检测原始值的方法就是用typeof,那么typeof Symbol返回的就是function类型。typeof Symbol(),好嘛!!!返回symbol类型。

在Javascript中函数即对象,是引用类型,为啥Symbol就是原始值,即基本类型呢?

好吧!阮一峰这里有解释说:

Symbol 值是原始类型,Symbol() 构造函数是对象。

Question:我们知道Number,Array,String,Boolean,Object都是可以进行实例化对象操作的,就是使用new操作符,思考下,number,string,boolean也是基本类型,为何就可以使用new,而Symbol()就不行呢?

解释下:symbol类型只能通过Symbol()函数的调用创建。symbol是基本类型,而Symbol()构造函数是个对象,既然是个构造器,为何就不能通过new操作符来实现一个实例化对象呢?

这里提及下Javascript的包装对象,有三种就是Boolean,Number,String。显示的创建包装对象是可以的,利用new Boolean()等方法,但是Symbol()函数对象内部阻止你显示创建一个symbol包装对象,所以你不能用new来创建一个symbol对象。只能通过Symbol("s")来创建一个基本数据类型——symbol类型。

如果你想创建一个Symbol包装对象,那么你可以先创建一个symbol基本类型值,然后通过Object()方法得到Symbol对象。"

敲黑板:

1,看栗子:

var s1 = 'abc'
var s2 = 'abc'
console.log(s1 === s2) //true
var sym1 = Symbol('abc')
var sym2 = Symbol('abc')
console.log(sym1 === sym2) //false
  console.log(Symbol.for('foo') === Symbol.for('foo'));//true

但是Symbol.for(key)方法返回一个全局的Symbol变量,不会每次都创建新的symbol,而是返回之前已经创建的symbol。这不就是单例模式嘛!

Symbol.keyFor(sym)方法返回定义symbol类型时传入的key字符串,如果没传入则为undefined。

Object.getOwnPropertySymbols(obj):返回一个数组,数组成员是对象的所有属性名为Symbol值。

const object1 = {};
const a = Symbol('a');
const b = Symbol.for('b'); object1[a] = 'localSymbol';
object1[b] = 'globalSymbol'; const objectSymbols = Object.getOwnPropertySymbols(object1);
console.log(objectSymbols)
// [Symbol(a), Symbol(b)]
Reflect.ownKeys(obj)
// [Symbol(a), Symbol(b)]

看阮一峰的文字呢,其实都是他自己的理解,每个人在对知识的理解上面会有些偏差,最好还是看官网吧。上面一段话意思是:Symbol()函数呢,返回一个类型为symbol的值,具有内置对象的静态属性和全局symbol的一些静态方法,类似于一个内置对象类,但是不能当做构造器函数,因为不支持“new Symbol()”语法。

每个symbol都是Symbol()函数返回的,唯一的,可以作为对象的属性名,这是symbol类型存在的唯一目的,其他用处可以去更多了解Symbol。symbol类型是原始值。

let sym = Symbol();

let obj = {
[sym]:"miya"
}
let a = {};
Object.defineProperty(a,sym,{value:'miya'}) console.log(obj[sym]) //miya
console.log(a[sym]) //miya

symbol值作为对象属性名只能通过[sym]来获取,不能通过点运算符。

对象的symbol类型属性名,只能通过Object.getOwnPropertySymbols(obj)获取,通过for...in/of或者其他都是不行的。

let s = Symbol();
let obj = {
[s](args){
console.log(args)
}
}
obj[s]('123') //

上面的例子是:给对象obj里面添加s的属性方法,使用ES6支持的函数的写法,函数名可以使用symbol原始值类型。

阮一峰举了一个使用symbol类型来消除魔术字的例子:

const shapeType = {
triangle:Symbol()
}
function getArea(shape,options){
let area = 0;
switch(shape){
case shapeType.triangle:
area = .5*options.width*options.height;
break;
}
return area;
}
getArea(shapeType.triangle,{width:100,height:100}) //

本来shapeType.triangle是个比较长的字符串,其实字符串是什么并不重要,只要属性值不冲突就行,刚好适合symbol的适用场景。

【完】

这两天都在了解Symbol类型,从最开始的云里雾里,扒了JS的包装对象,涨了些姿势。

ES6的原始类型数据——Symbol的更多相关文章

  1. ES6新特性:增加新类型:Symbol

    本文所有Demo的运行环境都为nodeJS, 参考:让nodeJS支持ES6的词法----babel的安装和使用 : ES6新增了一种数据类型:Symbol,Symbol是用来定义对象的唯一属性名的不 ...

  2. 理解ES6的新数据类型:Symbol

    ES6之前的数组类型 在ES6之前JS只有6种数据类型,分别是:Undefined.Null.布尔值(Boolean).字符串(String).数值(Number).对象(Object). ES6引入 ...

  3. JS中的原始类型和判断方法

    ECMAScript 中定义了 7 种原始类型: Boolean String Number Null Undefined Symbol(新定义) BigInt(新定义) 注意: 原始类型不包含 Ob ...

  4. [每日一题]ES6中为什么要使用Symbol?

    关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...

  5. ongl(原始类型和包装类型)

    原始类型和包装类型 //首先创建两个实体类 user 和 address user中包含address package cn.jbit.bean; public class User { //用户类 ...

  6. 01.JavaScript 面向对象精要--原始类型和引用类型

    一.什么是类型 JavaScript 虽然没有类的概念.但依然存在两种类型:原始类型和应用类型. 原始类型保存为简单的数据值,引用类型则保存为对象,其本质是指向内存位置 的引用.也就是说:原始值被直接 ...

  7. java 中的原始类型与原始封装类型

    Java   提供两种不同的类型:引用类型和原始类型(或内置类型).比如:Int是java的原始数据类型,Integer是java为int提供的封装类.Java为每个原始类型提供了封装类,常见的原始与 ...

  8. es6(四):Symbol,Set,Map

    1.Symbol: Symbol中文意思"象征" Symbol:这是一种新的原始类型的值,表示独一无二的值(可以保证不与其它属性名冲突) Symbol()函数前面不能使用new,因 ...

  9. 使用强类型实体Id来避免原始类型困扰(一)

    原文地址:https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-1/ 作者: ...

随机推荐

  1. 用Kinect为听障人士架一座沟通的桥梁

    编者按:这是微软亚洲研究院和中国科学院共同进行的一个合作项目,希望通过使用Kinect来帮助提升手语的识别率,从而为听力受损的残障人士(以下简称听障人士)架起一座与外界沟通的桥梁. 文章译自:Digi ...

  2. mysql操作命令梳理-grant授权和revoke回收权限

    在mysql维护工作中,做好权限管理是一个很重要的环节.下面对mysql权限操作进行梳理: mysql的权限命令是grant,权限撤销的命令时revoke:grant授权格式:grant 权限列表 o ...

  3. PMP备考经验总结-1906

    1.考试成绩 3A1T1B 2.考试背景(为什么考) 工作多年,做的项目很多,上到几百万,下到几万的项目,有自己的一套方法论,但是没有系统的对项目的知识做一次完整的梳理整合,觉得在整体把控上需要做一次 ...

  4. haproxy笔记之二:HAProxy简介

    HAProxy提供高可用性.负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费.快速并且可靠的一种解决方案.HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持 ...

  5. Nginx笔记总结十三:nginx 正向代理

    server { listen ; location / { resolver 202.106.0.20 202.106.119.116; resolver_timeout 30s; proxy_pa ...

  6. upper_bound()函数使用方法

    upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end.通过返回的地址减去起始地址beg ...

  7. Python---10小结

    因一边上班一边自学python,一旦忙起来,python就会放两天,可是2天后之前学的内容就会有点忘记. 今天把python的各种启动方法总结一下; 我的文档路径: ------- 1打开文件所在的c ...

  8. nginx 代理第三方邮件站点

    需求:公司业务服务器使用的是阿里云,要求内网(仅有内网IP)所有流量走网关服务器(有外网IP及内网IP),内网服务器需要调用一个公网上的第三方邮件站点.在参考了https://www.linuxba. ...

  9. Flask admin Flask login 整合模板

    项目地址: https://github.com/WES6/supflask Flask admin 官方文档: https://flask-admin.readthedocs.io/en/lates ...

  10. /lib64/libc.so.6: version `GLIBC_2.18' not found报错解决

    今日安装一区块链服务时报错:/lib64/libc.so.6: version `GLIBC_2.18' not found,检查后现有的glibc版本是2.17,然后参考https://www.ji ...