深入探讨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 相关文章推荐
清除网页历史记录,屏蔽后退按钮!
Dec 22 Javascript
js获取location.href的参数实例代码
Aug 02 Javascript
jquery mobile changepage的三种传参方法介绍
Sep 13 Javascript
通过js简单实现将一个文本内容转译成加密文本
Oct 22 Javascript
javaScript如何生成xmlhttp
Dec 16 Javascript
使用JQuery FancyBox插件实现图片展示特效
Nov 16 Javascript
jQuery和hwSlider实现内容响应式可触控滑动切换效果附源码下载(二)
Jun 22 Javascript
Google 地图类型详解及示例代码
Aug 06 Javascript
KnockoutJS 3.X API 第四章之数据控制流component绑定
Oct 10 Javascript
微信小程序版翻牌小游戏
Jan 26 Javascript
koa2服务端使用jwt进行鉴权及路由权限分发的流程分析
Jul 22 Javascript
详解element-ui 表单校验 Rules 配置 常用黑科技
Jul 11 Javascript
深入理解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
一个php短网址的生成代码(仿微博短网址)
2014/05/07 PHP
PHP仿微信发红包领红包效果
2016/10/30 PHP
ThinkPHP简单使用memcache缓存的方法
2016/11/15 PHP
php取出数组单个值的方法
2018/03/12 PHP
Thinkphp5.0 框架实现控制器向视图view赋值及视图view取值操作示例
2019/10/12 PHP
Nigma vs Liquid BO3 第一场2.14
2021/03/10 DOTA
jquery自动完成插件(autocomplete)应用之PHP版
2009/12/15 Javascript
jquery中加载图片自适应大小主要实现代码
2013/08/23 Javascript
jQuery对指定元素中指定字符串进行替换的方法
2015/03/17 Javascript
JavaScript控制两个列表框listbox左右交换数据的方法
2015/03/18 Javascript
javascript算法题:求任意一个1-9位不重复的N位数在该组合中的大小排列序号
2015/04/01 Javascript
JS+CSS实现自动切换的网页滑动门菜单效果代码
2015/09/14 Javascript
jquery ajaxfileuplod 上传文件 essyui laoding 效果【防止重复上传文件】
2018/05/26 jQuery
深入探讨JavaScript的最基本部分之执行上下文
2019/02/12 Javascript
layui数据表格实现重载数据表格功能(搜索功能)
2019/07/27 Javascript
用云开发Cloudbase实现小程序多图片内容安全监测的代码详解
2020/06/07 Javascript
koa2 数据api中间件设计模型的实现方法
2020/07/13 Javascript
js实现详情页放大镜效果
2020/10/28 Javascript
[07:54]DOTA2-DPC中国联赛 正赛 iG vs VG 选手采访
2021/03/11 DOTA
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
使用python调用浏览器并打开一个网址的例子
2014/06/05 Python
python脚本监控docker容器
2016/04/27 Python
解析Python中的eval()、exec()及其相关函数
2017/12/20 Python
python多进程中的内存复制(实例讲解)
2018/01/05 Python
Python实现爬虫爬取NBA数据功能示例
2018/05/28 Python
使用python获取(宜宾市地震信息)地震信息
2019/06/20 Python
django rest framework vue 实现用户登录详解
2019/07/29 Python
Django 创建新App及其常用命令的实现方法
2019/08/04 Python
python 3.7.4 安装 opencv的教程
2019/10/10 Python
python如何使用代码运行助手
2020/07/03 Python
HTML5实现自带进度条和滑块滑杆效果
2018/04/17 HTML / CSS
美国婴儿用品店:Babies”R”Us
2017/10/12 全球购物
GoPro摄像机美国官网:美国运动相机厂商
2018/07/03 全球购物
团员学习总结的自我评价范文
2013/10/14 职场文书
营销总经理的岗位职责
2013/12/15 职场文书
2014年信访工作总结
2014/11/17 职场文书