`

第三章 对象与JSON

 
阅读更多

JavaScript对象与传统的面向对象中的对象几乎没有相似之处,传统的面向对象语言中,创建一个对象必须先有对象的模板:类,类中定义了对象的属性和操作这些属性的方法。通过实例化来构筑一个对象,然后使用对象间的协作来完成一项功能,通过功能的集合来完成整个工程。而Javascript中是没有类的概念的,借助JavaScript的动态性,我们完全可以创建一个空的对象(而不是类),通过像对象动态的添加属性来完善对象的功能。

JSONJavaScript中对象的字面量,是对象的表示方法,通过使用JSON,可以减少中间变量,使代码的结构更加清晰,也更加直观。使用JSON,可以动态的构建对象,而不必通过类来进行实例化,大大的提高了编码的效率。

3.1 Javascript对象

JavaScript对象其实就是属性的集合,这里的集合与数学上的集合是等价的,即具有确定性,无序性和互异性,也就是说,给定一个JavaScript对象,我们可以明确的知道一个属性是不是这个对象的属性,对象中的属性是无序的,并且是各不相同的(如果有同名的,则后声明的覆盖先声明的)

一般来说,我们声明对象的时候对象往往只是一个空的集合,不包含任何的属性,通过不断的添加属性,使得该对象成为一个有完整功能的对象,而不用通过创建一个类,然后实例化该类这种模式,这样我们的代码具有更高的灵活性,我们可以任意的增删对象的属性。

如果读者有python或其他类似的动态语言的经验,就可以更好的理解JavaScript的对象,JavaScript对象的本身就是一个字典(dictionary),或者Java语言中的Map,或者称为关联数组,即通过键来关联一个对象,这个对象本身又可以是一个对象,根据此定义,我们可以知道JavaScript对象可以表示任意复杂的数据结构。

3.1.1 对象的属性

属性是由键值对组成的,即属性的名字和属性的值。属性的名字是一个字符串,而值可以为任意的JavaScript对象(JavaScript中的一切皆对象,包括函数)。比如,声明一个对象:

Js代码 复制代码
  1. //声明一个对象
  2. varjack=newObject();
  3. jack.name="jack";
  4. jack.age=26;
  5. jack.birthday=newDate(1984,4,5);
  6. //声明另一个对象
  7. varaddress=newObject();
  8. address.street="HuangQuanRoad";
  9. address.xno="135";
  10. //将addr属性赋值为对象address
  11. jack.addr=address;

这种声明对象的方式与传统的OO语言是截然不同的,它给了我们极大的灵活性来定制一个对象的行为。

对象属性的读取方式是通过点操作符(.)来进行的,比如上例中jack对象的addr属性,可以通过下列方式取得:

后者是为了避免这种情况,设想对象有一个属性本身包含一个点(.),这在JavaScript中是合法的,比如说名字为foo.bar,当使用jack.foo.bar的时候,解释器会误以为foo属性下有一个bar的字段,因此可以使用jack[foo.bar]来进行访问。通常来说,我们在开发通用的工具包时,应该对用户可能的输入不做任何假设,通过[属性名]这种形式则总是可以保证正确性的。

3.1.2属性与变量

在第二章,我们讲解了变量的概念,在本章中,读者可能已经注意到,这二者的行为非常相似,事实上,对象的属性和我们之前所说的变量其实是一回事。

JavaScript引擎在初始化时,会构建一个全局对象,在客户端环境中,这个全局对象即为window。如果在其他的JavaScript环境中需要引用这个全局对象,只需要在顶级作用域(即所有函数声明之外的作用域)中声明:

我们在顶级作用域中声明的变量将作为全局对象的属性被保存,从这一点上来看,变量其实就是属性。比如,在客户端,经常会出现这样的代码:

事实上相当于:

Js代码 复制代码
  1. window.v="global";
  2. window.array=["hello","world"];
  3. window.func=function(id){
  4. varelement=document.getElementById(id);
  5. //对elemen做一些操作
  6. }

3.1.3原型对象

原型(prototype),是JavaScript特有的一个概念,通过使用原型,JavaScript可以建立其传统OO语言中的继承,从而体现对象的层次关系。JavaScript本身是基于原型的,每个对象都有一个prototype的属性来,这个prototype本身也是一个对象,因此它本身也可以有自己的原型,这样就构成了一个链结构。

访问一个属性的时候,解析器需要从下向上的遍历这个链结构,直到遇到该属性,则返回属性对应的值,或者遇到原型为null的对象(JavaScript的基对象Objectprototype属性即为null),如果此对象仍没有该属性,则返回undefined.

下面我们看一个具体的例子:

Js代码 复制代码
  1. //声明一个对象base
  2. functionBase(name){
  3. this.name=name;
  4. this.getName=function(){
  5. returnthis.name;
  6. }
  7. }
  8. //声明一个对象child
  9. functionChild(id){
  10. this.id=id;
  11. this.getId=function(){
  12. returnthis.id;
  13. }
  14. }
  15. //将child的原型指向一个新的base对象
  16. Child.prototype=newBase("base");
  17. //实例化一个child对象
  18. varc1=newChild("child");
  19. //c1本身具有getId方法
  20. print(c1.getId());
  21. //由于c1从原型链上"继承"到了getName方法,因此可以访问
  22. print(c1.getName());

得出结果:

child
base

由于遍历原型链的时候,是有下而上的,所以最先遇到的属性值最先返回,通过这种机制可以完成重载的机制。

3.1.4 this指针

JavaScript中最容易使人迷惑的恐怕就数this指针了,this指针在传统OO语言中,是在类中声明的,表示对象本身,而在JavaScript中,this表示当前上下文,即调用者的引用。这里我们可以来看一个常见的例子:

Js代码 复制代码
  1. //定义一个人,名字为jack
  2. varjack={
  3. name:"jack",
  4. age:26
  5. }
  6. //定义另一个人,名字为abruzzi
  7. varabruzzi={
  8. name:"abruzzi",
  9. age:26
  10. }
  11. //定义一个全局的函数对象
  12. functionprintName(){
  13. returnthis.name;
  14. }
  15. //设置printName的上下文为jack,此时的this为jack
  16. print(printName.call(jack));
  17. //设置printName的上下文为abruzzi,此时的this为abruzzi
  18. print(printName.call(abruzzi));

运行结果:

jack
Abruzzi

应该注意的是,this的值并非函数如何被声明而确定,而是被函数如何被调用而确定,这一点与传统的面向对象语言截然不同,callFunction上的一个函数,详细描述在第四章。

3.2使用对象

对象是JavaScript的基础,我们使用JavaScript来完成编程工作就是通过使用对象来体现的,这一小节通过一些例子来学习如何使用JavaScript对象:

对象的声明有三种方式:

Ø 通过new操作符作用域Object对象,构造一个新的对象,然后动态的添加属性,从无到有的构筑一个对象。

Ø 定义对象的“类”:原型,然后使用new操作符来批量的构筑新的对象。

Ø 使用JSON,这个在下一节来进行详细说明

这一节我们详细说明第二种方式,如:

Js代码 复制代码
  1. //定义一个"类",Address
  2. functionAddress(street,xno){
  3. this.street=street||'HuangQuanRoad';
  4. this.xno=xno||135;
  5. this.toString=function(){
  6. return"street:"+this.street+",No:"+this.xno;
  7. }
  8. }
  9. //定义另一个"类",Person
  10. functionPerson(name,age,addr){
  11. this.name=name||'unknown';
  12. this.age=age;
  13. this.addr=addr||newAddress(null,null);
  14. this.getName=function(){returnthis.name;}
  15. this.getAge=function(){returnthis.age;}
  16. this.getAddr=function(){returnthis.addr.toString();}
  17. }
  18. //通过new操作符来创建两个对象,注意,这两个对象是相互独立的实体
  19. varjack=newPerson('jack',26,newAddress('QingHaiRoad',123));
  20. varabruzzi=newPerson('abruzzi',26);
  21. //查看结果
  22. print(jack.getName());
  23. print(jack.getAge());
  24. print(jack.getAddr());
  25. print(abruzzi.getName());
  26. print(abruzzi.getAge());
  27. print(abruzzi.getAddr());

运行结果如下:

jack
26
street : Qing Hai Road, No : 123
abruzzi
26
street : Huang Quan Road, No : 135

3.3 JSON及其使用

JSON全称为JavaScript对象表示法(JavaScript Object Notation),即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如:

这种方式,显然比上边的例子简洁多了,没有冗余的中间变量,很清晰的表达了obj这样一个对象的结构。事实上,大多数有经验的JavaScript程序员更倾向与使用这种表示法,包括很多JavaScript的工具包如jQueryExtJS等都大量的使用了JSONJSON事实上已经作为一种前端与服务器端的数据交换格式,前端程序通过Ajax发送JSON对象到后端,服务器端脚本对JSON进行解析,还原成服务器端对象,然后做一些处理,反馈给前端的仍然是JSON对象,使用同一的数据格式,可以降低出错的概率。

而且,JSON格式的数据本身是可以递归的,也就是说,可以表达任意复杂的数据形式。JSON的写法很简单,即用花括号括起来的键值对,键值对通过冒号隔开,而值可以是任意的JavaScript对象,如简单对象StringBooleanNumberNull,或者复杂对象如DateObject,其他自定义的对象等。

JSON的另一个应用场景是:当一个函数拥有多个返回值时,在传统的面向对象语言中,我们需要组织一个对象,然后返回,而JavaScript则完全不需要这么麻烦,比如:

直接动态的构建一个新的匿名对象返回即可:

使用JSON返回对象,这个对象可以有任意复杂的结构,甚至可以包括函数对象。

在实际的编程中,我们通常需要遍历一个JavaScript对象,事先我们对对象的内容一无所知。怎么做呢?JavaScript提供了for..in形式的语法糖:

这种模式十分有用,比如,在实际的WEB应用中,对一个页面元素需要设置一些属性,这些属性是事先不知道的,比如:

然后,我们给一个DOM元素动态的添加这些属性:

当然,jQuery有更好的办法来做这样一件事,这里只是举例子,应该注意的是,我们在给$("div#element")添加属性的时候,我们对style的结构是不清楚的。

另外比如我们需要收集一些用户的自定义设置,也可以通过公开一个JSON对象,用户将需要设置的内容填入这个JSON,然后我们的程序对其进行处理。

Js代码 复制代码
  1. functioncustomize(options){
  2. this.settings=$.extend(default,options);
  3. }

Js代码 复制代码
  1. for(variteminstyle){
  2. //使用jQuery的选择器
  3. $("div#element").css(item,style[item]);
  4. }

Js代码 复制代码
  1. varstyle={
  2. border:"1pxsolid#ccc",
  3. color:"blue"
  4. };

Js代码 复制代码
  1. for(variteminjson){
  2. //item为键
  3. //json[item]为值
  4. }

Js代码 复制代码
  1. varpos=point(3,4);
  2. //pos.x=3;
  3. //pos.y=4;

Js代码 复制代码
  1. functionpoint(left,top){
  2. this.left=left;
  3. this.top=top;
  4. //handletheleftandtop
  5. return{x:this.left,y:this.top};
  6. }

Js代码 复制代码
  1. varobj={
  2. name:"abruzzi",
  3. age:26,
  4. birthday:newDate(1984,4,5),
  5. addr:{
  6. street:"HuangQuanRoad",
  7. xno:"135"
  8. }
  9. }

Js代码 复制代码
  1. varv="global";
  2. vararray=["hello","world"];
  3. functionfunc(id){
  4. varelement=document.getElementById(id);
  5. //对elemen做一些操作
  6. }

Js代码 复制代码
  1. varglobal=this;

Js代码 复制代码
  1. varja=jack.addr;
  2. ja=jack[addr];

分享到:
评论

相关推荐

    第32章 JSON1

    2.解析和序列化 1.简单值:可以在 JSON 中表示字符串、数值、布尔值和 null 2.对象:顾名思义 3.数组:顾名思义

    javascript核心

    1.3 JavaScript内核系列 第3章 对象与JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 1.4 JavaScript内核系列 第4章 函数 . . . . . . . . . . . . . . ...

    JavaScript & jQuery 交互式Web前端开发

    更高效的学习JavaScript和...第3章 函数、方法与对象 第4章 判断和循环 第5章 文档对象模型 第6章 事件 第7章 jQuery 第8章 Ajax与JSON 第9章 API 第10章 错误处理与调试 第11章 内容面板 第12章 筛选、搜索与排序

    Python3入门视频教程百度网盘.pdf

    Python3⼊门视频教程百度⽹盘 视频内容: 第1章 Python⼊门导学 第2章 Python环境安装 第3章 理解什么是写代码与Python的基本类型 第4章 Python中表⽰"组"的概念与定义 第5章 变量与运算符 第6章 分⽀、循环、条件与...

    [Python3.X全栈开发]---- 入门与进阶视频教程.docx

    第3章 理解什么是写代码与Python的基本类型;第4章 Python中表示“组”的概念与定义;第5章 变量与运算符;第6章 分支、循环、条件与枚举;第7章 包、模块、函数与变量作用域;第8章 Python函数;第9章 高级部分:...

    Python3入门到进阶课程

    第3章理解什么是写代码与Python的基本类型.mp4 第4章Python中表示“组”的概念与定义.mp4 第5章变量与运算符.mp4 第6章分支、循环、条件与枚举.mp4 第7章包、模块、函数与变量作用域.mp4 第8章Python函数.mp4 第9章...

    全面系统Python3入门+进阶课程

    第3章理解什么是写代码与Python的基本类型.mp4 第4章Python中表示“组”的概念与定义mp4 第5章变量与运算符.mp4 第6章分支、循环、条件与枚举.mp4 第7章包、模块、函数与变量作用域,mp4 第8章Python函数.mp4 第9章...

    ActionScript 3.0 开发人员指南 (AS3开发帮助文档)

    第 3 章 : 使用数组 第 4 章 : 处理错误 第 5 章 : 使用正则表达式 第 6 章 : 使用 XML 第 7 章 : 使用本机 JSON 功能 第 8 章 : 处理事件 第 9 章 : 使用应用程序域 第 10 章 : 显示编程 第 11 章 : 使用...

    android知识大总结【邯院】

    第3章 硬件菜单 17 第4章 输入选择组件 19 第5章 图片和按钮 30 第6章 日期和时间控件 34 第7章 进度条和滑动条 37 第8章 GridView和Gallery控件 43 第9章 AutoCompleteTextView提示输入建议 48 第10章 RatingBar...

    第3章 实用VBA代码实例

    第3章_实用VBA代码实例,了解Excel VBA中的具体用法

    JavaScript核心概念及实践 高清PDF扫描版 (邱俊涛).pdf

    第3章 对象 第4章 函数 第5章 数组 第6章 正则表达式 第7章 闭包 第8章 面向对象的JavaScript 第9章 函数式的JavaScript 第10章 核心概念深入 第11章 客户端的JavaScript 第12章 客户端的MVC框架:...

    iOS编程教程,第2版

    第3章 内存管理 第4章 委托机制与Core Location 第5章 MapKit与文本输入 第6章 创建UIView子类 第7章 视图控制对象 第8章 方向感应器 第9章 通告机制与设备转动 第10章 UITableView与UITableViewController 第11章 ...

    Java高级程序设计实战教程第五章-Java序列化机制.pptx

    5.2 相关知识 5.2.1 序列化的概念 5.2.2 序列化应用 5.2.3 序列化的几种方式 5.2.4 对象实现机制 Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前为第3页。 5.2.1 序列化的概念 将在内存中的各种...

    JavaScript语言精粹.pdf

    第3章 对象 3.1 对象字面量 3.2 检索 3.3 更新 3.4 引用 3.5 原型 3.6 反射 3.7 枚举 3.8 删除 3.9 减少全局变量污染 第4章 函数 4.1 函数对象 4.2 函数字面量 4.3 调用 4.4 参数 4.5 返回 4.6 异常...

    javaee:java ee 项目的第一个 goncel 章

    开始 Java EE 7本书的结构第 1 部分 - 介绍第 1 章 - Java EE 7 环境第 2 节 - 交叉关注第 2 章 - 上下文和依赖注入第 3 章 - Bean 验证第 3 节 - 构建域模型第 4 章 - 坚持第 5 章 - 对象-关系映射第 6 章 - 管理...

    threeJS开发指南pdf版,内有git下载素材地址

    第3章 使用Three.js里的各种光源 3.1 探索Three.js库提供的光源 3.2 学习基础光源 3.3 总结 第4章 使用Three.js的材质 4.1 理解共有属性 4.2 从简单的网格材质(基础、深度和面)开始 4.3 学习高级材质 4.4 ...

    python入门到高级全栈工程师培训 第3期 附课件代码

    第3章 01 网络基础和dos命令 02 为何学习linux 03 课程内容介绍 04 操作系统内核与系统调用 05 操作系统安装原理 06 linux操作系统安装 07 初识linux命令 08 linux操作系统目录结构 09 目录及文件操作 第4章 01 ...

    python教程学习路线学习教程

    第3章函数 3.1自定义函数 3.2字符串函数 3.3集合类操作函数 3.4常用函数 第4章面向对象 4.1类和对象 4.2类的方法 4.3继承 4.4模块 第5章数据处理 5.1文件I/O 5.2JSON 和xml 解析 5.3csv 和excel 的高效解析 5.4异常 ...

Global site tag (gtag.js) - Google Analytics