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/ 作者: ...
随机推荐
- Fastjson主要接口和类库说明
2.主要的使用入口 Fastjson API入口类是com.alibaba.fastjson.JSON,常用的序列化操作都可以在JSON类上的静态方法直接完成. public static final ...
- Derby 命令
SHOW [ TABLES | VIEWS | PROCEDURES | FUNCTIONS | SYNONYMS ] { IN sche -- 列出表.视图.过程.函数或同义词 SHOW INDEX ...
- SHELL小练习
1.SHELL编程服务器IP修改脚本 脚本实现动态IP修改: 脚本实现静态IP修改: 实现IP地址输入判断正确性: IP地址修改成功判断&回滚: 2.SHELL编程Tomcat多实例管理脚本( ...
- python3多进程爬虫(第二卷)
上卷中讲到,我有4个进程,可是我要同时爬取20+数据怎么办,很明显上卷的语法公式不可以,所以现在我引入线程池 现在看一下线程池的语法 看一下爬虫: 注意圈中重点
- Nginx笔记总结十一:Nginx重写规则指南
依赖PCRE库,需要安装pcre,最多循环10次,超过后返回500错误, 1. rewrite模块指令 break:完成当前设置的重写规则,停止执行其他的重写规则 if: if () { ...
- unittest(7)-作业- 全局变量传递cookie
全局变量存储cookie 测试类中有多个测试函数 # 1.http_requset.py import requests class HttpRequest: def http_request(sel ...
- MariaDB 命令
1.账号登入 mysql -u root -p 上述命令,“root” 是登入账号,上述命令回车后,则进行密码的输入 登入成功后如下: 2.创建用户命令 create user 'new_user'@ ...
- 转:ZABBIX监控H3C设备的CPU和内存使用率
由于最近监控的H3C路由器经常出现死机现象,SNMP获取不到数据,后面检查发现是CPU使用率过高,直接导致无法处理SNMP请求,所以需求来了,怎样通过SNMP监控H3C路由器的CPU和内存使用率? ...
- Harbor快速搭建企业级Docker仓库
Github: https://github.com/goharbor/harbor 改端口安装: https://www.cnblogs.com/huangjc/p/6420355.html 相关博 ...
- SpringMVC之请求响应(上)
1.OutPutController package com.tz.controller; import java.util.Map; import org.springframework.stere ...