




已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
javascript 笔记:深入分析 javascript 里对象的创建 读 jQuery 源码时候,我常想到底那些因素会让我读不懂代码,其中最关键的是 哪个,最早觉得是 jQuery 的架构设计,当我查阅资料终于找到 jQuery 架构设 计的入口时候,我发现 javascript 基础语法的熟练运用才是读源码的关键,因 此现在把 javascript 基础知识系统回顾下很 有必要,而且 jQuery 源码的研究 就是对 javascript 基础知识的加深和灵活运用,我想后面临摹 jQuery 将和我 对 javascript 基础知 识的学习穿插起来,这样一定会对各种疑难问题有更好 的解答。 最近深入学习 javascript 后,有个体会:面向对象的方式编程才是高效灵 活的编程,也是现在唯一可以让代码更加健壮的编程方式。如果我们 抛开那些 玄乎的抽象出类等等思想,我自己对面向对象的从写程序的角度理解就是:复 用和封装。复用具体就是让你尽量少写重复代码,封装就是将一些耦合度很高 的逻辑放到一个程序块里,而且尽量让里面内容不受外界影响。最后的结论是: 优秀的 javascript 代码都是面向对象的。 今天要讲的是如何构建 javascript 对象。 ECMA-262 对对象的定义是:无序属性的集合,其属性可以包含基本值、对 象或函数。javascript 的对象其实就是 java 里的 map,即键值对。 在 javascript 创建一个对象一共有三种方式: 方式一:通过 Object 对象 方式二:通过构造函数 方式三:对象初始化 1.通过 Object 对象来构建对象,代码如下: /直接使用 Object 创建对象 var obj = new Object(); obj.id = 001; = My name is obj; obj.teststring = Test obj; obj.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); obj.sayHello();/id:001!name:My name is obj!teststring:Test obj objsayHello();/id:001!name:My name is obj!teststring:Test obj var str = sayHello; objstr();/id:001!name:My name is obj!teststring:Test obj 复制代码 (注意:我这里使用了两种访问对象属性的方式,一种是点运算符,一种是 方括号运算符,二者是等价的,但是方括号运算似乎要更强大些,方括号里面 我们可以放置变量) 这是最常用,最直观的一种创建对象方法,但是它的缺点太明显了,就是 代码复用度很低,我们想到一个对象就创建一个对象,如是就会造成大量的重 复代码,因此,javascript 程序员将工厂模式引入到了 javascrip 编程里,请 大家看下面的代码: / 用工厂模式创建对象 function createObj(id,name,teststring) var o = new Object(); o.id = id; = name; o.teststring = teststring; o.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); return o; var obj = createObj(002,My Name is obj2,Test Obj2); obj.sayHello();/id:002!name:My Name is obj2!teststring:Test Obj2 objsayHello();/id:002!name:My Name is obj2!teststring:Test Obj2 var str = sayHello; objstr();/id:002!name:My Name is obj2!teststring:Test Obj2 复制代码 工厂模式解决了创建相似对象的问题,如果抛开它构造对象的对象识别问 题,工厂模式挺完美的,如果你做的 javascript 应用不是太复杂,建 议使用 工厂模式构造对象,这种写法可读性很高。(写到工厂模式,我在临摹 jQuery 里面有段注解似乎不太正确,这个以后要修正)。 2.通过构造函数 在我前面的博文javascript 笔记:javascript 前世续篇(从 javascript 起源谈下它的继承) 里面我从 javascript 的起源里谈到了 javascript 面向对象的一些设计思想,其中就有关于 javascript 构造函数的 设计。几乎所有使用构造函数方式构建对象都会使用到 new 运算符, javascript 里面的构造函数比较特别的,在 javascript 里没有类的概念,new 后面跟的直接是构造函数,大家看下面的代码: / 使用构造函数创建对象 function Obj(id1,name1,teststring1) this.id = id1; = name1; this.teststring = teststring1; this.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); var obj = new Obj(003,My Name is obj3,Test Obj3); obj.sayHello();/id:003!name:My Name is obj3!teststring:Test Obj3 objsayHello();/id:003!name:My Name is obj3!teststring:Test Obj3 var str = sayHello; objstr();/id:003!name:My Name is obj3!teststring:Test Obj3 复制代码 构造函数式和工厂模式从代码角度而言很像,我在学习 javascript 初期, 单独看一种方式,思维总是惯性的把二者混为一谈,如果两个放在一 起还是觉 得有差异,主要是 javascript 里面 function 被赋予的功能太多,如果在一个 大型程序里面二者交替使用,不晕头才怪了。其实通过两者 构造对象的不同, 我可以把 function 的使用分为构造函数式和函数式。下面我将重点分析下两种 方式,这里的见底或许不全面,要是哪位高手看到了可以补充和指点哈。 首先我去掉方法里各个属性的 this 指针,而 sayHello 里面引用的 this 指 针不去掉。代码如下: / 深入分析构造函数 1 function Obj(id1,name1,teststring1) id = id1; name = name1; teststring = teststring1; sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); var obj = new Obj(004,My Name is obj4,Test Obj4); sayHello();/id:undefined!name:!teststring:undefined window.sayHello();/id:undefined!name:!teststring:undefined obj.sayHello();/obj.sayHello is not a function 在此错误处中断 obj.sayHello(); 复制代码 (纠正:sayHello();和 window.sayHello()结果是 id:004!name:My Name is obj4!teststring:Test Obj4,很抱歉,下面的一些分析也存在一些 问题,为了保证本文完整性,这里我只做纠正了,在下篇文章开篇我会着重分 析错误原因) this 永远指向 obj 的,而 sayHello 方法里的 this.id 等等属性的值为 undefined,表明 Obj 的 function 对象没 有 id,name,teststring 属性,就连 sayHello 方法在 Obj 里面也没有定义好,但是直接 sayHello();可以找到 sayHello 方法,最后我们使用 window.sayHello();才知道 sayHello 是被定义 在 window 里面了。如是我去掉 Obj 里面所 有 this,代码如下: / 深入分析构造函数 2 function Obj(id1,name1,teststring1) id = id1; name = name1; teststring = teststring1; sayHello = function() console.log(id: + id + !name: + name + !teststring: + teststring); var obj = new Obj(005,My Name is obj5,Test Obj5); sayHello();/id:005!name:My Name is obj5!teststring:Test Obj5 window.sayHello();/id:005!name:My Name is obj5!teststring:Test Obj5 console.log(id);/005 console.log(name);/My Name is obj5 console.log(teststring);/Test Obj5 console.log(window.id);/005 console.log();/My Name is obj5 console.log(window.teststring);/Test Obj5 复制代码 由上面内容我得出了下面的结论: 一.javascript 是可以做面向对象编程的,我们不能把它当做面向过程的 语言; 二.javascript 里面对象的创建是特别的,特别在于它和传统的面向对象 语言比较起来做了简化,简化到直接使用构造函数来创建对象; 三.function 在 javascript 里面既可以当做函数式使用,又可以作为构造 函数的标示(你也可以直接当做类来看待),而区别构造函数式和函数式的区 别就是 new; 四.如果我们用到了构造函数式才创建对象,那么这里和其他面向对象语言 一样,也是有封装的,换种说法是里面定义的属性或者方法是属于该对象的, 而让其属于该对象的方式就是用 this 指针,否则属性和方法将属于 window 对 象。 如果我们不用 new 运算符,直接使用函数,例如下面代码: / 深入分析函数式 1 function Obj(id1,name1,teststring1) this.id = id1; = name1; this.teststring = teststring1; this.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); Obj(006,My Name is obj6,Test Obj6); sayHello();/id:006!name:My Name is obj6!teststring:Test Obj6 window.sayHello();/id:006!name:My Name is obj6!teststring:Test Obj6 console.log(id);/006 console.log(name);/My Name is obj6 console.log(teststring);/Test Obj6 console.log(window.id);/006 console.log();/My Name is obj6 console.log(window.teststring);/Test Obj6 复制代码 直接调用 function,this 指针都是指向 window,也就是全局对象,我以 前看到过一句话:不论哪里直接调用函数,里面的 this 都是指向全局的。这个 不论哪里直接调用函数就有学问了啊,看下面代码: / 深入分析函数式 2 function OuterObj(id1,name1,teststring1) this.id = id1; = name1; this.teststring = teststring1; this.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); function InnerObj(id2,name2,teststring2) this.id = id2; = name2; this.teststring = teststring2; this.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); var innerVal = new InnerObj(101,InnerObj,Test InnerObj);/true console.log(innerVal instanceof InnerObj); innerVal.sayHello();/id:101!name:InnerObj!teststring:Test InnerObj InnerObj(102,InnerObj0,Test InnerObj0); var outObj = new OuterObj(007,My Name is obj7,Test Obj7); outObj.sayHello();/id:007!name:My Name is obj7!teststring:Test Obj7 sayHello();/ window.sayHello();/id:102!name:InnerObj0!teststring:Test InnerObj0 console.log(id);/102 console.log(name);/InnerObj0 console.log(teststring);/Test InnerObj0 复制代码 由此可见只要是函数调用 this 指向的方法和函数都是指向 window 的,即 全局对象。 3.对象初始化 对象初始化方式在有些书上也叫字面量方式构建对象,但是我更喜欢对象 初始化方式,这样更直观,代码如下: / 对象初始化 var obj = id:008, name:My Name is obj8, teststring:Test Obj8, sayHello:function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); ; obj.sayHello();/id:008!name:My Name is obj8!teststring:Test Obj8 objsayHello();/id:008!name:My Name is obj8!teststring:Test Obj8 var str = sayHello; objstr();/id:008!name:My Name is obj8!teststring:Test Obj8 复制代码 这种方式是我比较喜欢的一种构建对象的方式,有位 javascript 大师级的 人物曾经建议构建空对象,最好是 var obj = ,这句话就表明 var obj = 和 var obj = new Object();是等价的。var obj = 方式更加简洁,避免了 o.id; 等等繁琐的写法,jQuery 源码里面大量使用这样的构造对象的方 式。 以上就是我熟知的三种在 javascript 里面构建对象的方式。下面我将要换 个角度来理解 javascript 构建对象的知识。首先看一段 java 的代码: public class Obj public static String staticParams = “静态属性,它是属于类的“; private String objId = “编号是对象私有的“; public String objName = “名称是对象公有的“; /构造函数 public Obj() 复制代码 javascript 对象的属性或方法也可以使用 java 里的思想分为:属于类的 属性和方法,属于对象的属性或方法,还有公有属性和方法以及私有属性和方 法。 一.属于类的属性和方法:用对象初始化的方式都可以当做是属于类的属性 和方法,这种定义在 jQuery 里面大量运用; 二.属于对象的属性或方法:用构造函数的方式构建对象,里面用 this 指 针指向的属性和方法都是属于对象的; 三.公有属性和方法:javascript 里面属性和方法天生就是公有的; 四.私有属性和方法:这个在 javascript 里面要通过模拟才能实现,这种模 拟一般是使用作用域的原理,比如:在一个 function 内部用 var 来定义对象, 对象作用域属于改 function 内部,那么在函数外部是不能访问的,这就是私有 变量和方法了。 以上对象的创建,里面的属性和方法操作都是对象专有的,用相同方式构 建的类似对象不能做到信息的共享,那如何才能让类似的对象能共享信息了, 这就的使用 prototype 原型链了。 在 javascript 里面每个函数都有一个 prototype 属性,这个属性是一个指 针,指向一个对象,而这个对象的用途包含可以由特定类型所有实例共享的属 性和方法。 代码如下: /原型模式 function Obj(id1,name1,teststring1) this.id = id1; = name1; this.teststring = teststring1; this.sayHello = function() console.log(id: + this.id + !name: + + !teststring: + this.teststring); Ototype.objflag = 自建的 Obj 对象; OSayHello = function() console.log(Hello World and Obj); var obj1 = new Obj(008,My Name is obj8,Test Obj8); var obj2 = new Obj(009,My Name is obj9,Test Obj9); obj1.sayHello();/id:008!name:My Name is obj8!teststring:Test Obj8 obj2.sayHello();/id:009!name:My Name is obj9!teststring:Test Obj9 SayHello();/Hello World and Obj SayHello();/Hello World and Obj consol
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 学区房学位使用权购买合同年限约定及使用细则
- 电影院线与影视制作公司联合制作合同
- 工业遗存改造为文化创意空间的合作协议
- 智能物流解决方案AGV小车租赁与技术支持协议
- 智能健身仓健身APP开发与推广合作协议
- 商业航天测控技术培训与聘用一体化服务协议
- 企业班车运营安全责任承包合同
- 智能家居安防演示系统租赁与智能家居解决方案合作协议
- 旅游景区门票销售与托管运营合同
- 护理质量管理制度
- 虎符铜砭刮痧课件
- 数字媒体对人际亲密关系的影响机制研究
- 税务审计理论试题及答案解析
- 智能海洋牧场装备行业跨境出海战略研究报告
- 麻醉镇静药与阿片类
- 中考化学第一轮复习 物质的性质与应用(常见的酸碱盐)测试题(解析版)
- 病理学课件-炎症的机制
- 2025世界高血压日控住血压稳住幸福高血压健康讲座
- 安徽卓越县中联盟2024-2025学年高三下学期5月份检测政治试卷+答案
- 广东省珠海市2024-2025学年下学期期中八年级数学质量监测试卷(含答案)
- 焊接工程师职业技能考核试题及答案
评论
0/150
提交评论