探究javascript对象和数组的异同,及函数变量缓存技巧

news/2024/10/19 2:23:24/

 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


http://www.ppmy.cn/news/89846.html

相关文章

【TellMeCode】使用VSCODE + ChatGPT辅助分析推测源码

【TellMeCode】使用VSCODE ChatGPT辅助分析推测源码 0x00 功能简介 根据代码上下文相关信息,如工作区文件夹名称,代码所在路径等一系列信息,提供给大模型更多元和尽可能多的信息,利用其自身优势去检索相关的文档和博客&#xf…

IP协议-服务类型字段

服务类型(Type of Service)字段是比较复杂的一个字段,该字段经过多次标准变更。 IPv4报文 一、最初标准(RFC 791) RFC 791定义TOS字段总共占用8bit,分为IP Precedence优先级(3bit)、…

Dockerfile(1) - FROM 指令详解

FROM 指明当前的镜像基于哪个镜像构建dockerfile 必须以 FROM 开头&#xff0c;除了 ARG 命令可以在 FROM 前面 FROM [--platform<platform>] <image> [AS <name>]FROM [--platform<platform>] <image>[:<tag>] [AS <name>]FROM […

完美解决vue3 keep-alive多个路由使用同一个组件的缓存问题

之前页面少的话 用keep-live结合router-view&#xff0c;使用keep-live的include属性就可以自己决定keep-live缓存那些组件不缓存那些组件&#xff0c;直到遇到个问题。 平时写的代码如下&#xff1a; <router-view v-slot"{ Component, route }"><keep-al…

java面试应聘时的满分回答参考模板

java面试应聘时的满分回答参考模板 1、请你自我介绍一下自己好吗?2、你觉得你个性上最大的优点是什么?3、说说你最大的缺点?4、你对薪资的要求?5、你对加班的看法?6、如果通过这次面试我们录用了你,但工作一段时间却发现你根本不适合这个职位,你怎么办?7、谈谈你对跳槽…

第3章 单元测试-测验题-作业

在单元测试中&#xff0c;&#xff08;B &#xff09;是用来代替被测模块的子模块的。 驱动模块桩模块通讯模块代理模块在下面列举的测试覆盖中&#xff0c;&#xff08;D &#xff09;是最强的逻辑覆盖准则。 语句覆盖条件覆盖判定覆盖条件组合覆盖一个判定中的复合条件表达式…

【A卡,Windows】stable diffusion webui下载安装避坑指南

观前提醒 本文内容都是本人亲身经历的&#xff0c;一个一个安装下载测试所感&#xff0c;当然如果你更想用傻瓜式集成包的&#xff0c;那还是跳过这篇文章吧。 当然我不推荐这篇文章的操作&#xff0c;因为我用了差不多1h才有一副图&#xff0c;有N卡&#xff0c;就用N卡&…

零基础如何入门网络安全?2023年专业学习路线看这篇就够了

前景 很多零基础朋友开始将网络安全作为发展的大方向&#xff0c;的确&#xff0c;现如今网络安全已经成为了一个新的就业风口&#xff0c;不仅大学里开设相关学科&#xff0c;连市场上也开始大量招人。 那么网络安全到底前景如何&#xff1f;大致从市场规模、政策扶持、就业…