ES6的原始类型数据——Symbol
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
但是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的更多相关文章
- ES6新特性:增加新类型:Symbol
本文所有Demo的运行环境都为nodeJS, 参考:让nodeJS支持ES6的词法----babel的安装和使用 : ES6新增了一种数据类型:Symbol,Symbol是用来定义对象的唯一属性名的不 ...
- 理解ES6的新数据类型:Symbol
ES6之前的数组类型 在ES6之前JS只有6种数据类型,分别是:Undefined.Null.布尔值(Boolean).字符串(String).数值(Number).对象(Object). ES6引入 ...
- JS中的原始类型和判断方法
ECMAScript 中定义了 7 种原始类型: Boolean String Number Null Undefined Symbol(新定义) BigInt(新定义) 注意: 原始类型不包含 Ob ...
- [每日一题]ES6中为什么要使用Symbol?
关注「松宝写代码」,精选好文,每日面试题 加入我们一起学习,day day up 作者:saucxs | songEagle 来源:原创 一.前言 2020.12.23日刚立的flag,每日一题,题目 ...
- ongl(原始类型和包装类型)
原始类型和包装类型 //首先创建两个实体类 user 和 address user中包含address package cn.jbit.bean; public class User { //用户类 ...
- 01.JavaScript 面向对象精要--原始类型和引用类型
一.什么是类型 JavaScript 虽然没有类的概念.但依然存在两种类型:原始类型和应用类型. 原始类型保存为简单的数据值,引用类型则保存为对象,其本质是指向内存位置 的引用.也就是说:原始值被直接 ...
- java 中的原始类型与原始封装类型
Java 提供两种不同的类型:引用类型和原始类型(或内置类型).比如:Int是java的原始数据类型,Integer是java为int提供的封装类.Java为每个原始类型提供了封装类,常见的原始与 ...
- es6(四):Symbol,Set,Map
1.Symbol: Symbol中文意思"象征" Symbol:这是一种新的原始类型的值,表示独一无二的值(可以保证不与其它属性名冲突) Symbol()函数前面不能使用new,因 ...
- 使用强类型实体Id来避免原始类型困扰(一)
原文地址:https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-1/ 作者: ...
随机推荐
- swagger-ui不显示问题定位
1. 现象1 正常情况是 group会显示default/v2/api-docs 不知道是什么原因, 一个app可以展示,但另一个app不展示,配置也基本相同 1.1 定位过程 正常的app访问时的结 ...
- Python连接SQLServer2000
http://www.pymssql.org/en/stable/pymssql_examples.html 实例 import pymssql # 获取连接 conn = pymssql.conne ...
- 利用Python进行图片发送与接收的两种方法---包含客户端和服务器端代码
第一种方法 opencv.requests.flask 此方法比较耗费时间 600毫秒左右 客户端代码 #coding:utf-8 import cv2 import json import requ ...
- linux 下安装及查看java的安装路径
一.Linux下安装JDK 1.下载文件 从官网下载合适版本如:jdk-8u191-linux-x64.tar.gz 2.安装文件 1.在 /usr/ 目录下创建 java文件夹mkdir /usr/ ...
- leaflet本地加载arcgis切片
var origin = [-20037700, 33711400];//图层起点坐标 var resolutions = [ 8466.6836000338681, // Level 0 4233. ...
- windows下面 apache 虚拟主机配置
<VirtualHost > ServerAdmin www.test2.com DocumentRoot "D:/PHP/Apache/htdocs/testSite2&quo ...
- html和jsp页面中把文本框禁用,只能读不能写的方法
方法常用有三种: 第一种,使用 onfocus="this.blur()" <input name="deptno" type="text& ...
- LINQ之路 6:延迟执行(Deferred Execution) 笔记
这里刚看的时候不理解. 这个特性在我们通过foreach循环创建查询时会变成一个真正的陷阱.假如我们想要去掉一个字符串里的所有元音字母,我们可能会写出如下的query: IEnumerable< ...
- spring学习笔记一:spring介绍
jar包下载地址:http://repo.spring.io/release/org/springframework/spring/ spring特点: 1.非侵入性 spring框架的API不会在业 ...
- php--ip的处理
1.获取ip /**获取请求ip**/ function _get_request_ip(){ //strcasecmp 比较两个字符,不区分大小写.返回0,>0,<0. if(geten ...