深入探讨javascript中的数据类型


Posted in Javascript onMarch 04, 2015

学一门编程语言,无非两方面:一是语法,二是数据类型。类C语言的语法不外乎if、while、for、函数、算术运算等,面向对象的语言再加上object。
语法只是语言设计者预先做的一套规则,不同语言语法不尽相同,但都有一些共通点,对于熟悉一两门编程语言的人,学其他的编程语言时,语法往往不是问题(当然,如果你一直学的是类C语言,那么首次接触lisp时肯定也要花些时间),学习的重点往往是数据类型及其相关操作上,不是有句老话:“数据结构+算法=程序”!其次,有些语言的语法本身就存在设计问题(javascript更甚),我们没必要深究这些点,当然,如果你自诩geek,可以把玩把玩。

本文将对javascript中的数据类型做一个详尽的介绍。

弱类型 vs 强类型

鉴于javascript的设计理念,javascript被设计成一种弱类型的语言。
说到这里,难免要说一下,弱类型与强类型的区别。
一些人会误以为这两者的差别就是“强类型的语言在声明一个变量时需要指明它的类型,而弱类型的则不用”。其实这种观点是错误的。比如下面这个Java代码片段:

String s = "hello";

int l = s.getBytes().length;

编译器是怎么知道.length是合法的表达式呢?这是因为编译器知道s的数据类型为String,当调用String的getBytes方法时,返回值的数据类型为byte[],所以.length是合法的表达式。
这两者真正的区别是:

在强类型的语言,每个表达式的类型都能够在编译时确定,并且只允许适用于该类型的操作;
弱类型的语言允许对任意类型施加任何操作,只是这个操作有可能在运行时报错。
数据类型

根据ECMAScript 5.1的规范,javascript中共有六种数据类型,分别为:Undefined, Null, Boolean, Number, String、Object。前五种属于基本类型,最后一种属于对象类型。

基本数据类型

Undefined类型只有一个值,为undefined,意味着“空值(no value)”,适用于所有数据类型。
Null类型只有一个值,为null,意味着“空对象(no object)”,只适用于对象类型。
Boolean类型有两个值,为true与false
Number类型的值是遵循IEEE 754标准的64位浮点数的集合,类似于Java的double。没有整型数据结构。此外还包含三个特殊的值:NaN、Infinity、-Infinity
String类型的值是有穷个Unicode字符的集合。必须用'或"括起来。

null与undefined

null与undefined都表示“没有值(non-value)”的概念,如果严格区分:
- null表示空
- undefined表示不存在。没有初始化的变量、函数中缺失的参数、函数没有显式return值时都为此值

在其他语言中,一般只用一个null来表示空值,javascript中为什么多了个undefined呢?这是历史原因造成的:

javascript采用了Java的语法,把类型分为了基本类型与对象类型,Java中用null来表示空对象,javascript想当然的继承了过来;在C语言中,null在转为数字时为0,javascript也采取同样的方式:

> Number(null)

0

> 5 + null

5

在javascript1.0时,还没有异常处理(exception handling),对于一些异常情况(没有初始化的变量、调用函数时缺失的参数等),需要标明为一种特殊的值,null本来是个很好的选择,但是Brendan Eich同时想避免下面两件事:
- 这个特殊值不应该有引用的特性,因为那是对象特有的
- 这个特殊值不应该能转为0,因为这样不容易发现程序中的错误
基于这两个原因,Brendan Eich选择了undefined,它可以被强转为NaN。

> Number(undefined)

NaN

> 5 + undefined

NaN

两者在于JSON对象打交道时,结果也迥然不同:

> JSON.parse(null)

null

> JSON.parse(undefined)

//Firfox SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data

//Chrome SyntaxError: Unexpected token u

> JSON.stringify(null)

"null"

> JSON.stringify(undefined)

undefined

对象类型

javascript作为一门脚本语言,本身功能十分精简,很多功能(文件读写、网络等)都是由宿主环境提供。宿主环境与javascript语言的桥梁是对象,宿主环境通过提供一系列符合javascript语法的对象,提供各种各样的功能。

在javascript面向对象编程这篇文章(如果你不知道prototype是什么,强烈建议看看这篇文章)里,我多次强调了对象在javascript中就是一系列的键值对,就像Java中的HashMap一样,不过,javascript中对象的属性可以有一些描述符(property descriptor),这在HashMap中是没有的。

属性描述符

属性描述符分为两类:

数据描述符(data descriptor),包含一系列boolean值,用以说明该属性是否允许修改、删除。
访问描述符(accessor descriptor),包含get与set函数。
这两种描述符都是对象,它们都拥有下面两个boolean属性:

configurable 用以指定该描述符是否允许修改、删除。默认为false。
enumerable 用以指定在遍历对象(使用for...in循环或Object.keys方法)的属性时,是否访问该属性。默认为false。
除了上面这两个共有属性外,数据描述符还有下面两个属性:
- value 用以指定该属性的值,默认为undefined
- writable 用以指定该属性的值是否允许改变该属性的值,默认为false

访问描述符还有下面两个属性:
- get 用以指定访问该属性时的访问器(getter,本质是个函数),该访问器的返回值为该属性的值。默认为undefined
- set 用以指定访问该属性时的赋值器(setter,本质是个函数),该赋值器的接受一个参数。默认为undefined

我们可以使用Object.defineProperty来设置对象的属性描述符。例如:

// using __proto__

Object.defineProperty(obj, 'key', {

  __proto__: null, // no inherited properties

  value: 'static'  // not enumerable

                   // not configurable

                   // not writable

                   // as defaults

});

通过上面这个例子可以看出,描述符具有继承的特点,我们这里显式的把描述符对象的__proto__设为null,就避免了从Object.prototype中继承相应属性。当然我们也可以显式地设置描述符的所有属性:

// being explicit

Object.defineProperty(obj, 'key', {

  enumerable: false,

  configurable: false,

  writable: false,

  value: 'static'

});

这样的效果和第一段代码的效果是一样的。

下面再举一个访问描述符的例子:

// Example of an object property added with defineProperty with an accessor property descriptor

var bValue = 38;

Object.defineProperty(obj, 'key', {

  get: function() { return bValue; },

  set: function(newValue) { bValue = newValue; },

  enumerable: true,

  configurable: true

});

需要注意的是,不能混淆了访问描述器与数据描述器。下面这样写是错误的:

// You cannot try to mix both:

Object.defineProperty(obj, 'conflict', {

  value: 0x9f91102,

  get: function() { return 0xdeadbeef; }

});

// throws a TypeError: property descriptors must not specify a value 

// or be writable when a getter or setter has been specified

typeof

如果想在运行时获知某变量的类型,可以使用typeof操作符。typeof的返回值如下表:

深入探讨javascript中的数据类型

其中有一处需要注意,那就是typeof null == "object",按照ECMAScript 5.1标准,Null类型应该是个基本类型,为什么这里返回object呢?原因是这样的:

在javascript 1.0中,javascript中的值是用一个类型标志(type tag)和一个实际值这样的结构表示的,对象的类型标志为0,null在C语言中表示NULL指针(0x00),所以null的类型标志就为0了。

以上就是本文的全部内容了,有需要的小伙伴参考下吧。

Javascript 相关文章推荐
正则表达式语法
Oct 09 Javascript
js中for in的用法示例解析
Dec 25 Javascript
jQuery设置和获取HTML、文本和值示例
Jul 08 Javascript
JavaScript中使用Math.floor()方法对数字取整
Jun 15 Javascript
React-Native使用Mobx实现购物车功能
Sep 14 Javascript
JS处理一些简单计算题
Feb 24 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
Sep 14 Javascript
mocha的时序规则讲解
Feb 16 Javascript
微信小程序用户拒绝授权的处理方法详解
Sep 20 Javascript
《javascript设计模式》学习笔记一:Javascript面向对象程序设计对象成员的定义分析
Apr 07 Javascript
vue项目在线上服务器访问失败原因分析
Aug 14 Javascript
jquery实现淡入淡出轮播图效果
Dec 13 jQuery
深入理解JavaScript系列(49):Function模式(上篇)
Mar 04 #Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
Mar 04 #Javascript
jQuery中大家不太了解的几个方法
Mar 04 #Javascript
深入理解JavaScript系列(48):对象创建模式(下篇)
Mar 04 #Javascript
js计算德州扑克牌面值的方法
Mar 04 #Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
Mar 04 #Javascript
深入理解JavaScript系列(46):代码复用模式(推荐篇)详解
Mar 04 #Javascript
You might like
?生?D片??C字串
2006/12/06 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
Javascript面向对象编程
2012/03/18 Javascript
js修改table中Td的值(定义td的双击事件)
2013/01/10 Javascript
用JS做的简单的可折叠的两级树形菜单
2013/09/21 Javascript
jQuery插件windowScroll实现单屏滚动特效
2015/07/14 Javascript
onclick和onblur冲突问题的快速解决方法
2016/04/28 Javascript
mac上node.js环境的安装测试
2017/07/03 Javascript
详解React中的组件通信问题
2017/07/31 Javascript
vue2.x select2 指令封装详解
2017/10/12 Javascript
详解koa2学习中使用 async 、await、promise解决异步的问题
2018/11/13 Javascript
javascrit中undefined和null的区别详解
2019/04/07 Javascript
vue项目打包上传github并制作预览链接(pages)
2019/04/19 Javascript
layui监听select变化,以及设置radio选中的方法
2019/09/24 Javascript
vue 实现特定条件下绑定事件
2019/11/09 Javascript
Vue列表循环从指定下标开始的多种解决方案
2020/04/08 Javascript
微信小程序实现天气预报功能(附源码)
2020/12/10 Javascript
[01:33]一分钟玩转DOTA2第三弹:DOTA2&DotA快捷操作大对比
2014/06/04 DOTA
基于python yield机制的异步操作同步化编程模型
2016/03/18 Python
利用python在excel里面直接使用sql函数的方法
2019/02/08 Python
python交互界面的退出方法
2019/02/16 Python
python分割一个文本为多个文本的方法
2019/07/22 Python
python 协程中的迭代器,生成器原理及应用实例详解
2019/10/28 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
python3代码输出嵌套式对象实例详解
2020/12/03 Python
blueseventy官网:铁人三项和比赛泳衣
2021/02/06 全球购物
财务会计专业应届毕业生求职信
2013/10/18 职场文书
会计与出纳自荐书范文
2014/03/16 职场文书
主题实践活动总结
2014/05/08 职场文书
入党积极分子批评与自我批评思想汇报
2014/09/14 职场文书
学生抄袭作业的检讨书
2014/10/02 职场文书
关于群众路线的心得体会
2014/11/05 职场文书
2015年幼儿园元旦游艺活动策划书
2014/12/09 职场文书
毕业生个人总结
2015/02/28 职场文书
2015迎新晚会开场白
2015/05/29 职场文书
践行三严三实心得体会(2016推荐篇)
2016/01/06 职场文书