这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
这篇文章主要介绍了深入探讨 javascript 中的数据类型, 需要的朋友可以参考下
学一门编程语言,无非两方面:一是语法,二是数据类型。类 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 的返回值如下表:
其中有一处需要注意,那就是 typeof null == "object",按照 ECMAScript 5.1 标准,Null 类型应该是个基本类型,为什么这里返回 object 呢?原因是这样的:
在 javascript 1.0 中,javascript 中的值是用一个类型标志(type tag)和一个实际值这样的结构表示的,对象的类型标志为 0,null 在 C 语言中表示 NULL 指针(0x00),所以 null 的类型标志就为 0 了。
来源: http://www.phperz.com/article/17/0502/272462.html