浅析在javascript中创建对象的各种模式

上传人:bin****86 文档编号:59391736 上传时间:2018-11-07 格式:DOCX 页数:14 大小:20.26KB
返回 下载 相关 举报
浅析在javascript中创建对象的各种模式_第1页
第1页 / 共14页
浅析在javascript中创建对象的各种模式_第2页
第2页 / 共14页
浅析在javascript中创建对象的各种模式_第3页
第3页 / 共14页
浅析在javascript中创建对象的各种模式_第4页
第4页 / 共14页
浅析在javascript中创建对象的各种模式_第5页
第5页 / 共14页
点击查看更多>>
资源描述

《浅析在javascript中创建对象的各种模式》由会员分享,可在线阅读,更多相关《浅析在javascript中创建对象的各种模式(14页珍藏版)》请在金锄头文库上搜索。

1、我真正系统地接触和学习党的基本知识是在这次中级党校的培训班上。通过学习,了解了党的发展历程,对党的性质、宗旨、任务等基本知识有了进一步的了解浅析在javascript中创建对象的各种模式下面小编就为大家带来一篇浅析在javascript中创建对象的各种模式。小编觉得挺不错的,现在分享给大家,也给大家做个参考。最近在看javascript高级程序设计(第二版)javascript中对象的创建工厂模式构造函数模式原型模式结合构造函数和原型模式原型动态模式面向对象的语言大都有一个类的概念,通过类可以创建多个具有相同方法和属性的对象。虽然从技术上讲,javascript是一门面向对象的语言,但是jav

2、ascript没有类的概念,一切都是对象。任意一个对象都是某种引用类型的实例,都是通过已有的引用类型创建;引用类型可以是原生的,也可以是自定义的。原生的引用类型有:Object、Array、Data、RegExp、Function。 !引用类型就是一种数据结构,将数据和功能组织在一起,通常被称为类。 缺乏类概念的javascript中,需要解决的问题就是如何高效的创建对象。1.1.0.创建对象的一般方法var person = ; /对象字面量表示,等同于var person = new Objcect();person.name = evansdiy;person.age = 22;pers

3、on.friends = ajiao,tiantian,pangzi;person.logName = function() console.log(this.name);基于Object引用类型,创建了一个对象,该对象包含四个属性,其中一个为方法。如果需要很多类似person的实例,那就会有许多重复的代码。1.1.1.工厂模式 top通过一个可以包含了对象细节的函数来创建对象,然后返回这个对象。function person(name,age,friends) var o = name: name, age: age, friends: friends, logName: function(

4、) console.log(this.name); ; return o;var person1 = person(Evansdiy,22,ajiao,tiantian,pangzi);每次调用person函数,都会通过该函数内部的对象o创建新的对象,然后返回,除此之外,这个为了创建新对象而存在的内部对象o没有其他的用途。另外,无法判断工厂模式创建的对象的类型。1.1.2.构造函数模式 topfunction Person(name,age,job) this.name = name; this.age = age; this.job = job; this.logName = functio

5、n() console.log(this.name); /通过new操作符创建Person的实例var person1 = new Person(boy-a,22,worker);var person2 = new Person(girl-b,23,teacher);person1.logName(); /boy-aperson2.logName(); /girl-a对比工厂模式,可以发现,这里并不需要创建中间对象,没有return。另外,可以将构造函数的实例标识为一种特定的类型,这就解决了对象识别的问题(通过检查实例的constructor属性,或利用instanceof操作符检查该实例是否

6、通过某个构造函数创建)。console.log(person1.constructor = Person);/constructor位于构造函数原型中,并指向构造函数,结果为trueconsole.log(person1 instanceof Person);/通过instanceof操作符,判断person1是否为构造函数Person的实例但构造函数模式也有自己的问题,实际上,logName方法在每个实例上都会被重新创建一次,需要注意的是,通过实例化创建的方法且并不相等,以下代码将会得到false:console.log(person1.logName = person2.logName);

7、/false我们可以将方法移到构造器外部(变为全局函数)来解决这个问题:function logName() console.log(this.name);function logAge() console.log(this.age);但是,在全局下创建的全局函数实际上只能被经由Person创建的实例调用,这就有点名不副实了;如果方法很多,还需要逐一定义,缺少封装性。1.1.3.原型模式 topjavascript中的每一个函数都包含一个指向prototype属性的指针(大部分浏览器可以通过内部属性_proto_访问),prototype属性是一个对象,其中包含了由某种引用类型创建的所有实例共

8、享的属性和方法。 function Person() Person.name = evansdiy;Person.prototype.friends = ajiao,jianjian,pangzi;Person.prototype.logName = function() console.log(this.name);var person1 = new Person();person1.logName();/evansdiy以上代码做了这几件事情:1.定义了一个构造函数Person,Person函数自动获得一个prototype属性,该属性默认只包含一个指向Person的constructor

9、属性;2.通过Person.prototype添加三个属性,其中一个作为方法;3.创建一个Person的实例,随后在实例上调用了logName()方法。这里需要注意的是logName()方法的调用过程:1.在person1实例上查找logName()方法,发现没有这个方法,于是追溯到person1的原型2.在person1的原型上查找logame()方法,有这个方法,于是调用该方法 基于这样一个查找过程,我们可以通过在实例上定义原型中的同名属性,来阻止该实例访问原型上的同名属性,需要注意的是,这样做并不会删除原型上的同名属性,仅仅是阻止实例访问。var person2 = new Person

10、();person2.name = laocai;如果我们不再需要实例上的属性时,可以通过delete操作符删除。delete person2.name;利用for-in循环枚举出实例可以访问到的所有属性(不论该属性存在于实例或是原型中):for(i in person1) console.log(i);同时,也可以利用hasOwnProperty()方法判断某个属性到底存在于实例上,还是存在于原型中,只有当属性存在于实例中,才会返回true:console.log(person1.hasOwnProperty(name);/true!hasOwnProperty来自Object的原型,是ja

11、vascript中唯一一个在处理属性时不查找原型链的方法。via javascript秘密花园 另外,也可以通过同时使用in操作符和hasOwnProperty()方法来判断某个属性存在于实例中还是存在于原型中:console.log(friends in person1) & !person1.hasOwnProperty(friends);先判断person1是否可以访问到friends属性,如果可以,再判断这个属性是否存在于实例当中(注意前面的!),如果不存在于实例中,就说明这个属性存在于原型中。 前面提到,原型也是对象,所以我们可以用对象字面量表示法书写原型,之前为原型添加代码的写法可

12、以修改为:Person.prototype = name: evansdiy, friends: ajiao,jianjian,pangzi, logName: function() console.log(this.name); 由于对象字面量语法重写了整个prototype原型,原先创建构造函数时默认取得的constructor属性会指向Object构造函数:/对象字面量重写原型之后console.log(person1.constructor);/Object不过,instanceof操作符仍会返回希望的结果:/对象字面量重写原型之后console.log(person1 instanc

13、eof Person);/true当然,可以在原型中手动设置constructor的值来解决这个问题。Person.prototype = constructor: Person, .如果在创建对象实例之后修改原型对象,那么对原型的修改会立即在所有对象实例中反映出来:function Person() ;var person1 = new Person();Person.prototype.name = evansdiy;console.log(person1.name);/evansdiy实例和原型之间的连接仅仅是一个指针,而不是一个原型的拷贝,在原型实际上是一次搜索过程,对原型对象的所做的

14、任何修改都会在所有对象实例中反映出来,就算在创建实例之后修改原型,也是如此。 如果在创建对象实例之后重写原型对象,情况又会如何?function Person() ;var person1 = new Person1();/创建的实例引用的是最初的原型/重写了原型Person.prototype = friends: ajiao,jianjian,pangzivar person2 = new Person();/这个实例引用新的原型console.log(person2.friends);console.log(person1.friends);以上代码在执行到最后一行时会出现未定义错误,如果我们用for-in循环枚举person1中的可访问属性时,会发现,里头空无一物,但是person2却可以访问到原型上的friends属性。 !重写原型切断了现有原型与之前创建的所有对象实例的联系,之前创建的对象实例的原

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 总结/报告

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号