本文主要描述Javascript的数据模型,即对Javascript所支持的数据类型的一个全局概缆。文章比较的理论化,非常深入,因此不易理解,但务必对数据模型有一个映象,因为他是理解Javascript对象模型与Javascript执行模型的基础。

基本的数据类型

 原始类型(简单数据类型、基本数据类型)

Undefined类型: 表示声明了变量但未对其初始化时赋予该变量的值。undefined为Undefined类型下的唯一的一个值。

Null类型:用于表示尚未存在的对象。Null类型下也只有一个专用值null。

Boolean类型:有两个值true和false,主要用于条件判断,控制执行流程。

Number类型:代表数字(即包括32的整数,也包括64位的浮点数)

String类型:用于代表字符串。

对象:一个无序属性的集合,这些属性的值为简单数据类型、对象或者函数。注:这里对象并不特指全局对象Object.

函数:函数是对象的一种,实现上内部属性[[Class]]值为"Function",表明它是函数类型,除了对象的内部属性方法外,还有 [[Construct]]、[[Call]]、[[Scope]]等内部属性。函数作为函数调用与构造器(使用new关键字创建实例对象)的处理机制不一样(Function对象除外),内部方法[[Construct]]用于实现作为构造器的逻辑,方法[[Call]]实现作为函数调用的逻辑。同上,这里的函数并不特指全局对象Function。

注:关于函数与对象的关系可以引申出很多问题,现在可以不去深究函数实现内部的细节,这将在以后的文章中探讨。

内置数据类型(内置对象)

Function: 函数类型的用户接口。 Object: 对象类型的用户接口。 Boolean, Number, String: 分别为这三种简单数值类型的对象包装器,对象包装在概念上有点类似C#/Java中的Box/Unbox。 Date, Array, RegExp: 可以把它们看作是几种内置的扩展数据类型。

首先,Function, Object, Boolean, Number, String, Date, Array, RegExp等都是JavaScript语言的内置对象,它们都可以看作是函数的派生类型,例如Number instanceof Function为true,Number instanceof Object为true。在这个意义上,可以将它们跟用户定义的函数等同看待。 其次,它们各自可以代表一种数据类型,由JS引擎用native code或内置的JS代码实现,是暴露给开发者对这些内置数据类型进行操作的接口。在这个意义上,它们都是一种抽象的概念,后面隐藏了具体的实现机制。 在每一个提到Number, Function等单词的地方,应该迅速的在思维中将它们实例化为上面的两种情况之一。

数据类型实现模型描述

Build-in *** data structure: 指JS内部用于实现***类型的数据结构,由宿主环境(浏览器)提供,这些结构我们基本上无法直接操作。 Build-in *** object: 指JS内置的Number, String, Boolean等这些对象,这是JS将内部实现的数据类型暴露给开发者使用的接口。 Build-in *** constructor: 指JS内置的一些构造器,用来构造相应类型的对象实例。它们被包装成函数对象暴露出来,例如我们可以使用下面的方法访问到这些函数对象:

1
2
3
4
5
6
7
8
9
10
11
12
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
//access the build-in number constructor
var number = new Number(123);
var numConstructor1 = number.constructor; //or
var numConstructor2 = new Object(123).constructor;
//both numConstructor1 and numConstructor2 are the build-in Number constructor
numConstructor1 == numConstructor2 //result: true
//access the build-in object constructor
var objConstructor1 = {}.constructor; //or
var objConstructor2 = new Object().constructor;
//both objConstructor1 and objConstructor2 are the build-in Object constructor
objConstructor1==objConstructor2 //result: true

关于"接口"的解释:简单的说,接口就是可以调用的方法。如:

1
2
3
4
5
6
7
8
//String就是一个接口,它定义了String的行为.它可以由外部调用
var str = new String('笨蛋的座右铭');
//我们自已定义一个接口
function say(msg){
   alert(msg);
}
//调用定义的接口
say("hello world");

注:完全理解接口的概念需要有一定的强类型语言编程经验(java/c#),因为本文已经够复杂了,就不再将问题复杂化了。所以对于接口的答案并不是很严谨,但已经够用了,望高人见谅。

关于简单数据类型的对象化

这是一个细微的地方,下面描述对于Boolean, String和Number这三种简单数值类型都适用,以Number为例说明。 JS规范要求: 使用var num1=123;这样的代码,直接返回基本数据类型,就是说返回的对象不是派生自Number和Object类型,用num1 instanceof Object测试为false;使用new关键字创建则返回Number类型,例如var num2=new Number(123); num2 instanceof Number为true。 将Number当作函数调用,返回结果会转换成简单数值类型。下面是测试代码:

1
2
3
4
5
6
7
8
9
10
11
//Passed in FF2.0, IE7, Opera9.25, Safari3.0.4
var num1 = new Number(123); //num1 derived from Number & Object
num1 instanceof Number //result: true
num1 instanceof Object //result: true
//convert the num1 from Number type to primitive type, so it's no longer an instance of Number or Object
num1 = Number(num1);
num1 instanceof Number //result: false
num1 instanceof Object //result: false
var num2 = 123; //num2 is a primitive type
num2 instanceof Number //result: false
num2 instanceof Object //result: false

结论:虽然我们得到了一个简单数值类型,但它看起来仍然是一个JS Object对象,具有Object以及相应类型的所有属性和方法,使用上基本没有差别,唯一不同之处是instanceof的测试结果。由此也就产生了一个概念"Literal Syntax"

Literal Syntax

在简单数据类型的对象化一节中,我们也看到了简单类型和其包装类型可以相互转换,并且两者之间的行为相同。但两者相比较,明显简单类型的定义更加轻量,因此我们可以用简单类型定义替换相应的包装类型定义。如:

1
2
3
Number: var i = 100; //替代var i = new Number(100);
Boolean: var b = true//替代var b = new Boolean(true);
String: var str = 'this is a string.'; //替代var str = new String('this is a string');

其实这种类似于var i = 100;var b=true;var str='this is a string'这种定义方式就叫做Literal Syntax。难道就只有简单数据类型才有这种Literal Syntax的表示方法吗!不是的,复合数据类型同样有。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//对象定义的字面量表示法
var obj  = {name:'笨蛋的座右铭',age:25}
/*
//对象的非字面量表示法
var obj = new Object();
obj.name = '笨蛋的座右铭';
obj.age = 25;
*/
 
//数组定义的字面量表示法
var arr = ['笨蛋的座右铭',25];
/*
//数组的非字面量表示法
var arr = new Array();
arr[0]='笨蛋的座右铭'];
arr[1]=25;
*/
 
//正则表达式字面量表式法
var reg = /\d+/;
/*
//正则表达式非字面量表式法
var reg = new RegExp("\\d+");
*/

那函数呢!其实函数的定义已经是Literal Syntax的表示形式了。

在实际工作中,我们建议尽量采用Literal Syntax的形式定义变量,因为这样更简单,更高效。

Javascript数据模型的更多相关文章

  1. 【JavsScript】JavaScript MVC 框架技术选型

    你很喜欢Gmail和Trello之类的单页面应用,但是不太确定该从何开始.也许你的JavaScript代码是如此的杂乱无章,以致于你很想在下一个项目上尝试下JavaScript MVC库和框架,却苦于 ...

  2. 数据的双向绑定 Angular JS

    接触AngularJS许了,时常问自己一些问题,如果是我实现它,会在哪些方面选择跟它相同的道路,哪些方面不同.为此,记录了一些思考,给自己回顾,也供他人参考. 初步大致有以下几个方面: 数据双向绑定 ...

  3. 数据的双向绑定 Angular JS之开端篇

    接触AngularJS许了,时常问自己一些问题,如果是我实现它,会在哪些方面选择跟它相同的道路,哪些方面不同.为此,记录了一些思考,给自己回顾,也供他人参考. 初步大致有以下几个方面: 数据双向绑定 ...

  4. 深入学习AngularJS中数据的双向绑定机制

    来自:http://www.jb51.net/article/80454.htm Angular JS (Angular.JS) 是一组用来开发Web页面的框架.模板以及数据绑定和丰富UI组件.它支持 ...

  5. ASP.NET MVC 5 - 给数据模型添加校验器

    在本节中将会给Movie模型添加验证逻辑.并且确保这些验证规则在用户创建或编辑电影时被执行. 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DRY: "不要重复自己(DRY ...

  6. ASP.NET MVC 5 -从控制器访问数据模型

    在本节中,您将创建一个新的MoviesController类,并在这个Controller类里编写代码来取得电影数据,并使用视图模板将数据展示在浏览器里. 在开始下一步前,先Build一下应用程序(生 ...

  7. 顶级的JavaScript框架、库、工具及其使用

    几乎每隔一个星期,就有一个新的 JavaScript 库席卷网络社区!Web 社区日益活跃.多样,并在多个领域快速成长.想要研究每一个重要的 JavaScript 框架和库,是个不可能完成的任务.接下 ...

  8. 初识NodeJS,一个基于GoogleV8引擎的Javascript运行环境

    思考 首先我们来思考一个问题:我们都知道几乎所有现代主流浏览器都全面支持了ECMAScript 5.1版标准,而JavaScript的标准是ECMAScript.那么我们就容易认为JavaScript ...

  9. django开发个人简易Blog——数据模型

    提到数据模型,一定要说一下MVC,MVC框架是现代web开发中最流行的开发框架,它将数据与业务逻辑分开,减小了应用之间的高度耦合.个人非常喜欢MVC开发框架,除了具有上述特性,它使得web开发变得非常 ...

随机推荐

  1. python进阶之魔法函数

    __repr__ Python中这个__repr__函数,对应repr(object)这个函数,返回一个可以用来表示对象的可打印字符串.如果我们直接打印一个类,向下面这样 class A():     ...

  2. python的map/reduce区别

    直接上列子 map: 把f(x)作用在list的每一个元素并把结果生成一个新的list” # coding=utf-8def f(x): return x * x r = map(f, [1, 2, ...

  3. javascript 模拟按键点击提交

    上代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...

  4. spring动态加载(刷新)配置文件 [复制链接]

    待验证 在程序开发时,通常会经常修改spring的配置文件,不得不重启tomcat来加载spring配,费时费力.如果能在不重启tomcat的情况下,手动动态加载spring 配置文件,动态重启读取s ...

  5. 详解PHP的执行原理和流程

    简介 先看看下面这个过程: • 我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的: • PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程 ...

  6. SUSE Enterprise Server 12 SP3 64 设置防火墙开放8080端口,出现Unsafe permissions for file /etc/sysconfig/SuSEfirewall2 to be sourced

    SUSE Enterprise Server  12 SP3 64 设置防火墙开放8080端口时出现  Unsafe permissions for file /etc/sysconfig/SuSEf ...

  7. ruby语言学习笔记2

    ruby学习笔记2  (摘自<ruby程序设计语言教程(中文版)>.pdf,全书25页) 1.同一个问题ruby有多个解决方案,途径 ruby之父:松本行弘(Matz),1993年创立 r ...

  8. 项目管理工具Maven的安装与使用

    一.Maven的简介 1. 什么是maven 是Apache下的一个开源的项目,是纯java编写,并且只是用来管理java项目. 2. Maven的好处 maven项目管理jar节省磁盘空间 一键构建 ...

  9. Codeforces 379F New Year Tree 树的直径的性质推理

    New Year Tree 我们假设当前的直径两端为A, B, 那么现在加入v的两个儿子x, y. 求直径的话我们可以第一次dfs找到最远点这个点必定为直径上的点, 然而用这个点第二次dfs找到最远点 ...

  10. js判断设备是都是pc端

    function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = new Array("Android" ...