目前阶段JavaScript中的数据类型,一共8种,主要分类两大类型:基本类型和引用类型
基本类型又叫做简单类型或者值类型,引用类型又叫做复杂类型;
基本类型(按值访问):在存储时变量中存储的是值本身,因此也叫做值类型;
引用类型(按引用访问):在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型;
介绍一下堆和栈:
栈 (stack)
:用来保存简单的数据字段
堆(heap)
:用来保存栈中简单数据字段对指针的引用
区别:
1、栈(操作系统):
由操作系统自动分配释放存放函数的参数值、局部变量的值等,其操作方式类似于数据结构中的栈;
简单数据类型直接存放到栈里面。
2、堆(操作系统):
存储复杂类型,一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收;
复杂数据类型引用放在栈里面,实际数据存放到堆里面。
为啥会导致上述区别,是因为:
1、基本类型的数据简单,所占用空间比较小,内存由系统自动分配;
2、引用类型数据比较复杂,复杂程度是动态的,计算机为了较少反复的创建和回收引用类型数据所带来的损耗, 就先为其开辟另外一部分空间——即堆内存,以便于这些占用空间较大的数据重复利用;
3、堆内存中的数据不会随着方法的结束立即销毁,有可能该对象会被其它方法所引用, 直到系统的垃圾回收机制检索到该对象没有被任何方法所引用的时候才会对其进行回收。
具体点,举个小栗子看看实际的影响:
// 基本数据类型
let a = 1;
let b = a;
b = 2;
console.log(a, b) // 1, 2
复制代码
// 引用数据类型
let obj1 = {a: 1, b: 2};
let obj2 = obj1;
obj2.a = 20;
console.log(obj1.a, obj2.a) // 20, 20
复制代码
由于篇幅原因,前面五个老生常谈的基本类型就略过了... , 看看下面三个:
1、Symbol
Symbol 本质上是一种唯一标识符,可用作对象的唯一属性名,这样其他人就不会改写或覆盖你设置的属性值。声明方法:
let id = Symbol("id");
复制代码
Symbol 数据类型的特点是唯一性,即使是用同一个变量生成的值也不相等。
let id1 = Symbol('id');
let id2 = Symbol('id');
console.log(id1 == id2); //false
复制代码
Symbol 数据类型的另一特点是隐藏性,for···in
和 object.keys()
不能访问
let id = Symbol("id");
let obj = {
[id]:'symbol'
};
for(let option in obj){
console.log(obj[option]); //空
}
复制代码
但是也有能够访问的方法:Object.getOwnPropertySymbols
, 该方法会返回一个数组,成员是当前对象的所有用作属性名的 Symbol
值。
let id = Symbol("id");
let obj = {
[id]:'symbol'
};
let array = Object.getOwnPropertySymbols(obj);
console.log(array); //[Symbol(id)]
console.log(obj[array[0]]); //'symbol'
复制代码
虽然这样保证了Symbol
的唯一性,但我们不排除希望能够多次使用同一个symbol
值的情况。为此,官方提供了全局注册并登记的方法:Symbol.for()
let name1 = Symbol.for('name'); //检测到未创建后新建
let name2 = Symbol.for('name'); //检测到已创建后返回
console.log(name1 === name2); // true
复制代码
通过这种方法就可以通过参数值获取到全局的symbol
对象了,反之,能不能通过symbol
对象获取到参数值呢?是可以的 ,通过Symbol.keyFor()
let name1 = Symbol.for('name');
let name2 = Symbol.for('name');
console.log(Symbol.keyFor(name1)); // 'name'
console.log(Symbol.keyFor(name2)); // 'name'
复制代码
最后,提醒大家一点,在创建symbol类型数据 时的参数只是作为标识使用,所以 Symbol()
也是可以的。
2、BigInt
BigInt
数据类型提供了一种方法来表示大于2^53-1的整数。BigInt
可以表示任意大的整数。
Number
类型只能安全的支持-9007199254740991(-(2^53-1))
和 9007199254740991(2^53-1)
之间的整数,任何超过这个范围的数值都会失去精度;而BigInt
可以解决这个问题
console.log(9007199254740999) //9007199254741000
console.log(9007199254740993===9007199254740992) //true
12
复制代码
上图,当数值超过Number数据类型支持的安全范围值时,将会被四舍五入,从而导致精度缺失的问题
1、方式一:在整数的末尾追加n
console.log(9007199254740999n); //9007199254740999
复制代码
2、方式二:调用BigInt()
构造函数
let bigInt = BigInt("9007199254740999"); //传递给BigInt()的参数将自动转换为BigInt
console.log(bigInt); //9007199254740999n
复制代码
1、BigInt
除了不能使用一元加号运算符外,其他的运算符都可以使用
console.log(+1n); // Uncaught TypeError: Cannot convert a BigInt value to a number
console.log(-1n); //ok
复制代码
2、BigInt
和Number
之间不能进行混合操作
console.log(1n+5)
复制代码
如果希望使用BigInt
和Number
执行算术计算,首先需要确定应该在哪个类型中执行该操作。为此,只需通过调用Number()
或BigInt()
来转换操作数:
BigInt(10) + 10n; // → 20n
// 或者(在同一环境中操作)
10 + Number(10n); // → 20
复制代码
1、BigInt
数据类型提供了一种方法来表示大于2^53-1
或者小于-2^53-1
的整数,BigInt
可以表示任意大的整数;
2、不能使用Number
和BigInt
操作数的混合执行算术运算,需要通过显式转换其中的一种类型,使得两者在同一环境中操作;
3、此外,出于兼容性原因,不允许在BigInt
上使用一元加号(+
)运算符。
3、Object(万物皆对象)
Js
中常用的引用类型有:Object
,Array
,Function
, Date
, RegExp
等
带有属性和方法的特殊数据类型;
创建Object实例的方式有两种。第一种是使用new操作符后跟Object构造函数,例如;
let person = new Object();
person.name = "Nicholas";
person.age = 29;
console.log(person instanceof Object); // true
复制代码
另一种方式是使用对象字面量表示法。例如:
let person = {
name : "Nicholas",
age ; 29
}
console.log(person instanceof Object); // true
复制代码
注意:在通过对象字面量定义对象时,实际上不会调用Object构造函数。
是使用单独的变量名来存储一系列的值;
创建数组的基本方式有两种。第一种是使用Array构造函数,例如:
let colors = new Array();
console.log(colors instanceof Array); // true
复制代码
第二种基本方式是使用数组字面量表示法。数组字面量由一对包含数组项的方括号表示,多个数组项之间以逗号隔开,例如:
let colors = ["red","blue","green"];
console.log(colors instanceof Array); // true
复制代码
函数类型在JavaScript中也是对象
函数实际上是对象,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数通常是使用函数声明语法定义的:(函数声明提升)
function sum (sum1,sum2) {
return sum1 + sum2;
}
console.log(sum instanceof Function); // true
复制代码
还有一种方式,使用函数表达式定义函数:
let sum = function(sum1,sum2) {
return sum1 +sum2 ;
};
console.log(sum instanceof Function); // true
复制代码
其他的引用类型具体细节可以看看这篇文章,内容较多就不一一列举了:
juejin.cn/post/691441…[1]
2.1、typeof
先看一下用法:
// 基本类型
console.log(typeof "");
console.log(typeof 1);
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof null); // object---有点儿特殊,见下
console.log(typeof Symbol('id'))
console.log(typeof 9007199254740999n)
console.log(typeof BigInt(9007199254740999))
// 引用类型
console.log(typeof []);
console.log(typeof function(){});
console.log(typeof {});
复制代码
结果:
图片.png
关于基础类型null
,使用typeof
返回的是object
的说明,来个官方文档贴图:
图片.png
小结
通过上面的无脑console.log
,可以看出typeof
可以用于检测基本类型(除了null
);
不同的数据类型在底层都是通过二进制表示的,二进制前三位为000
则会被判断为object
类型,而null底层的二进制全都是0,那前三位肯定也是000
,所以被判断为object
;
但碰到引用类型均返回为object
,无法精准判定。
2.2、instanceof
用法:
// 基本类型
console.log('1' instanceof String)
console.log(1 instanceof Number)
console.log(true instanceof Boolean)
// console.log(undefined instanceof undefined)
// Uncaught TypeError: Right-hand side of 'instanceof' is not an object
// console.log(null instanceof null)
// Uncaught TypeError: Right-hand side of 'instanceof' is not an object
console.log(typeof Symbol('id') instanceof Symbol)
console.log(typeof 9007199254740999n instanceof BigInt)
console.log(typeof BigInt(9007199254740999) instanceof BigInt)
// 引用类型
console.log([] instanceof Array)
console.log(function () {} instanceof Function)
console.log({} instanceof Object)
复制代码
结果:
图片.png
小结
不难看出,instanceof
可以用于引用类型的检测,但对于基本类型是不生效的;
另外,不能用于检测null
和undefined
, 会抛错。
2.3、constructor
先看一下用法:
// 基本类型
console.log('1'.constructor === String)
console.log((1).constructor === Number)
console.log(true.constructor === Boolean)
// console.log(undefined.constructor === Boolean)
// Uncaught TypeError: Cannot read properties of undefined (reading 'constructor')
// console.log(null.constructor === Boolean)
// Uncaught TypeError: Cannot read properties of undefined (reading 'constructor')
console.log(Symbol('id').constructor === Boolean)
console.log(9007199254740999n.constructor === Boolean)
console.log(BigInt(9007199254740999).constructor === Boolean)
// 引用类型
console.log([].constructor === Array)
console.log(function () {}.constructor === Function)
console.log({}.constructor === Object)
复制代码
结果:
图片.png
撇去null、undefined、Symbol、BigInt,似乎说constructor能用于检测js的基本类型和引用类型
但当涉及到原型和继承的时候,便出现了问题,如下:
function fun() {};
fun.prototype = new Array();
let f = new fun();
console.log(f.constructor===fun); // false
console.log(f.constructor===Array); // true
复制代码
在这里,我们先是定义了一个函数fun,并将该函数的原型指向了数组,同时,声明了一个f为fun的类型,然后利用constructor进行检测时,会发现并不符合预期
小结
撇去null、undefined、Symbol、BigInt
,constructor
能用于检测js
的基本类型和引用类型,但当对象的原型更改之后,constructor
便失效了。
2.4、Object.prototype.toString.call()
用法:
let test = Object.prototype.toString
// 基本类型
console.log(test.call('str'))
console.log(test.call(1))
console.log(test.call(true))
console.log(test.call(null))
console.log(test.call(undefined))
console.log(test.call(Symbol('id')))
console.log(test.call(9007199254740999n))
console.log(test.call(BigInt(9007199254740999)))
// 引用类型
console.log(test.call([]))
console.log(test.call(function () {}))
console.log(test.call({}))
复制代码
结果:
图片.png
得到结果之后, 你可以通过:xxx.slice(8, \-1).toLowerCase()
,就可拿来正常使用咯;
这样一看,似乎能满足js
的所有数据类型,那我们看下继承之后是否能检测出来:
function fun() {};
fun.prototype = new Array();
let f = new fun();
console.log(Object.prototype.toString.call(fun))
console.log(Object.prototype.toString.call(f))
复制代码
结果:
图片.png
小结
可以看出,Object.prototype.toString.call()
可用于检测js
所有的数据类型,完美~
文字看的真是难受?来个表吧:
图片.png
图片.png
参考文档链接:
developer.mozilla.org/zh-CN/docs/…[2]
es6.ruanyifeng.com/#docs/symbo…[3]
juejin.cn/post/684490…[4]
juejin.cn/post/691441…[5]
blog.csdn.net/yiyueqinghu…[6]
blog.csdn.net/m0\_50914413…[7]
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/17SY8AEGY3AyspA3xLNHcw
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。