javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象。这篇重点要提到的,就是任何jser都不陌生的Object和Array。

  有段时间曾经很诧异,到底两种数据类型用来存储数据有什么不同。于是,我打算探究探究。

 一、掌握三种数据类型

  首先,一个前提必须掌握的,就是必须理解javascript的数据类型分类,主要分为以下三种:

  第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。

  第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如"北京,上海"。

  第三种类型是映射(mapping),也就是一个键/值对(key/value),即数据有一个键名,还有一个与之相对应的键值,这又称作散列/哈希(hash)或字典(dictionary),比如"首都:北京"。

  从这里也可知道对象就是一种映射类型的数据,数组是一种序列类型的数据。

  比较细致的解答,可以参考阮一峰的博文《数据类型和Json格式

  

 二、声明和实例化方式

  1.对象的声明和实例化  
  

//第一种方式
var obj = new Object();
obj.name = "wall"; //第二种方式
var obj = {};
obj.name = "wall"; //第三种方式
var obj = {
"name" : "wall"
}; //第三种方式的简约版
var obj = {
name : "wall" //key减少了一对双引号
}; //第四种方式
var obj = {};
obj["name"] = "wall";

  

  2.数组的声明和实例化

  

//第一种方式
var arr = new Array();
arr[0] = "wall"; //第二种方式
var arr = [];
arr[0] = "wall"; //第三种方式
var arr = ["wall"]; //第四种方式
var arr = [];
arr.push("wall"); //诡异的第五种方式,也是后面讲的一个重点
var arr = [];
arr["name"] = "wall";

 三、使用方式

//输出对象中name的值
console.log(obj.name);
//或
console.log(obj["name"]); //输出数组中name的值
console.log(arr[0]); //输出数组声明的第五种方式中的值
console.log(arr["name"]);

 四、比较

  以上可以看出,其实在简单的数据存储要求上,选择数组和选择对象进行存储,差别不是很大,而且两者均可以用下标的方式进行访问,所以有时自己都有疑惑到底二者区别到底在哪里。

  最简单的不同就是:对象,系统默认是没有length属性的,而数组是默认有length属性的。而这,又牵扯出一个有趣的现象:

  在chrome的控制台下,输出一个简单的例子

  

  到这里,肯定会有人感到奇怪,为什么变量b的长度会是0! 为什么不是1。

  为了验证我的想法,就再编写一个例子:

  

  原来,b["test"]这个键值并没有放入数组的序列中去,那会跑哪里去了?于是我查了下b这个变量的结构,然后再重新实例化一个新的变量b,比较其不同,终于找到原因:

              

  原来,test是作为数组的一个属性值进行存储,而不是添加到数组的数据序列中去,顿时豁然开朗,呵呵~

  这里也可以得出一个结论:数组是一个可以存储序列类型数据的对象,即是对对象的继承和扩展。数组的序列类型数据,可以通过整数下标进行读写操作,而其自定义的属性值,则可以通过对象访问属性值的方式进行访问,二者互不干扰。

 五、对象实例化中需要注意的地方  

//第三种方式
var obj = {
"name" : "wall"
}; //第三种方式的简约版
var obj = {
name : "wall" //key减少了一对双引号
};

  虽然这两种方式看起来没什么不同,都可以使用obj.name进行访问,但是这里推荐第三种方式,而不要用简约版。

  原因就是如果用简约版的方式进行实例化,键名如果是javascript保留的关键字,在 ECMAScript 5 之前会抛出SyntaxError 的错误(来自javascript秘密花园的解释)。

 六、函数变量缓存的技巧

  我就不多说,直接先上代码:

//定义函数
var fun = function(options){
if(!arguments.callee.arr){
arguments.callee.arr = {
"name":"wall",
"who":"jser"
};
console.log("init");//标识是否调用初始化
} return arguments.callee.arr[options];
} //访问name
console.log(fun("name")); //访问who
console.log(fun("who"));

  运行结果如下:

  所以,很明显地,数据只要初始化一次,就会保存在当前函数对象下,作为它的一个属性值,下次操作就可以避免重复性的工作了。

  可能很多读者还不是很明白arguments.callee是什么,其实它指向的就是调用当前方法的对象,也即是fun。

  这样写的原因是,在实际生产过程中,多人协作编码,可能有人会一不小心把你这里的function改个名字什么的,那缓存的作用就失效了,甚至会出错。不过有个缺点就是在严格模式下,arguments.callee会被禁用。

  最后,再贴上一个未做上面这个优化的代码,其实效果也一样(其实就是将arguments.callee替换成fun)。

//定义函数
var fun = function(options){
if(!fun.arr){
fun.arr = {
"name":"wall",
"who":"jser"
};
console.log("init");//标识是否调用初始化
} return fun.arr[options];
} //访问name
console.log(fun("name")); //访问who
console.log(fun("who"));

  另外,这里的arguments.callee也可以替换成this指针,不过,调用的时候就要注意this指针的指向,这里可以用new function()的方式调用。

via:cnblogs.com/walls/p/4281531.html

探究javascript对象和数组的异同,及函数变量缓存技巧的更多相关文章

  1. 第一百零三节,JavaScript对象和数组

    JavaScript对象和数组 学习要点: 1.Object类型 2.Array类型 3.对象中的方法 什么是对象,其实就是一种类型,即引用类型.而对象的值就是引用类型的实例.在ECMAScript中 ...

  2. JavaScript 对象与数组参考大全

    http://www.cnblogs.com/meil/archive/2006/06/28/437527.html本文列举了各种JavaScript对象与数组,同时包括对上述每一对象或数组所完成工作 ...

  3. javascript中对象和数组的异同点

    一.JS声明对象或数组 JS对象:{ } JS数组:[ ] 对象 var b={m:'123',n:'abc'};alert(b.m);alert(b.n); 一维数组 var a=[1,2,3];a ...

  4. JavaScript对象和数组

    1.JavaScript中有两个非常重要的数据类型是对象和数组. 通过"."或者"[]"来访问对象属性 举例:var book = { topic:" ...

  5. 简述JavaScript对象、数组对象与类数组对象

    问题引出 在上图给出的文档中,用JavaScript获取那个a标签,要用什么办法呢?相信第一反应一定是使用document.getElementsByTagName('a')[0]来获取.同样的,在使 ...

  6. javascript 对象和数组(花括号、方括号)

    1. javascript对象定义 var a = {var a = "test", var b = "test"} 2. javascript数组定义 var ...

  7. JavaScript对象与数组

    一.Object 类型到目前为止,我们使用的引用类型最多的可能就是 Object 类型了.虽然 Object 的实例不具备多少功能,但对于在应用程序中的存储和传输数据而言,它确实是非常理想的选择.创建 ...

  8. javascript对象初探(一)--- 构造器函数

    我们可以通过构造器函数(简称构造函数)来创建对象: function Her(){ this.child = 'Jon'; } 为了使用该函数来创建对象,我们需要使用new操作符,例如: var sh ...

  9. 精彩的javascript对象和数组混合相加

    最近遇到一个让人困解的一个问题:一个简单的js加法运算表达式: +[]; //这里加上一个空数组得到什么???答案:'1'; 为什么答案是1,一开始我也很困惑:后来我读了一篇文章才知道:在javasc ...

随机推荐

  1. AndroidTips-052:.aar文件依赖

    aar aar 文件是android 类库项目的输出文件,其中可以包含普通的.class,清单,以及android项目特有的资源文件. 使用方式 将.aar文件放在在自己项目的libs目录下 在gra ...

  2. 11、Struts2 的文件上传和下载

    文件上传 表单准备 要想使用 HTML 表单上传一个或多个文件 须把 HTML 表单的 enctype 属性设置为 multipart/form-data 须把 HTML 表单的method 属性设置 ...

  3. CRL快速开发框架系列教程七(使用事务)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  4. Struts2实现ajax的两种方式

    基于Struts2框架下实现Ajax有两种方式,第一种是原声的方式,另外一种是struts2自带的一个插件. js部分调用方式是一样的: JS代码: function testAjax() { var ...

  5. C#日志

    参考页面: http://www.yuanjiaocheng.net/Entity/first.html http://www.yuanjiaocheng.net/Entity/jieshao.htm ...

  6. 网站里加入QQ在线客服

    1.开启"QQ在线状态"服务  http://jingyan.baidu.com/article/b24f6c823425a586bfe5da1f.html http://www. ...

  7. AEAI DP V3.6.0 升级说明,开源综合应用开发平台

    AEAI DP综合应用开发平台是一款扩展开发工具,专门用于开发MIS类的Java Web应用,本次发版的AEAI DP_v3.6.0版本为AEAI DP _v3.5.0版本的升级版本,该产品现已开源并 ...

  8. Hibernate 系列 学习笔记 目录 (持续更新...)

    前言: 最近也在学习Hibernate,遇到的问题差不多都解决了,顺便把学习过程遇到的问题和查找的资料文档都整理了一下分享出来,也算是能帮助更多的朋友们了. 最开始使用的是经典的MyEclipse,后 ...

  9. HTML5 程序设计 - 使用HTML5 Canvas API

    请你跟着本篇示例代码实现每个示例,30分钟后,你会高喊:“HTML5 Canvas?!在哥面前,那都不是事儿!” 呵呵.不要被滚动条吓到,很多都是代码和图片.我没有分开写,不过上面给大家提供了目录,方 ...

  10. 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的

    数组和泛型容器有什么区别 要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance).逆变性(contravariance)和无关性(invariant). 若类A是类B的子类, ...