《Javascript高级程序设计》读书笔记之——Prototype

来源:互联网 发布:专业定制软件 编辑:程序博客网 时间:2024/05/20 03:46

0. 写在前面

创建对象:

var person = new Object();person.name = "Nicholas";person.age = 24;person.job = "Engineer";person.sayName = function(){      alert(this.name);};

如果需要通过接口创建大量对象,那么会产生大量重复代码,工厂模式抽象了创建具体对象的过程。

构造函数:

function Person(name, age, job) {       this.name = name;       this.age = age;       this.job = job;       this.sayName = sayName;}function sayName() {       alert(this.name);}var person1 = new Person("Nicholas", 24, "Engineer");var person2 = new Person("Greg", 30, "Doctor");
但构造函数需要在每个实例上都重新创建一遍。全局作用域中定义的函数实际上只能被某个对象调用。

这些问题都可以通过原型模式来解决。

1. 原型模式

事实上每个函数都有其prototype属性,这个属性是一个指向对象的指针,而这个对象就是该类函数所共享的属性和方法。
prototype相当于提供了一个初始值,当给对象实例添加了新的属性,新的属性就会覆盖prototype提供的原始值。如果删掉对象的属性,那么访问到的就是prototype设定的值。不同的对象实例共享一个prototype,减少了冗余度。
function Person(){}Person.prototype = {    name : "Nicholas",    age : 24,    job : "Engineer",    sayName : function(){        alert(this.name);    } };var p1 = new Person();p1.name = "Greg";p1.age = 30;
也就是说,在Person这个原型中,包含constructor, name, age, job, sayName 4个部分。
p1中包含指向原型的指针,还有name, age两个新的属性。访问时候没有新的job和sayName属性,返回时会继续向上搜索,返回原型中的job和sayName属性。
而且由于在原型中查找是一次搜索过程,那么在对象申明之后,给原型中添加新的属性,也是能够成功返回的。
var p2 = new Person();Person.prototype.sayHi = function(){    alert("Hi");}p2.sayHi();
调用pa.sayHi()时,首先会在实例中搜索,没找到的情况下,会继续向上搜索原型。

2. 原型对象的问题

使用原型模式穿件的实例,在默认情况下都取得相同的属性值,在某种情况下会带来不便。

但如果在原型中包含引用类型,问题会更大。

function Person(){}Person.prototype = {    name : "Nicholas",    age : 24,    job : "Engineer",    friends : ["Chris", "Flex"],    sayName : function(){        alert(this.name);    } };var p1 = new Person();var p2 = new Person();p1.friends.push("Lorry");alert(p1.friends);  //"Chris, Flex, Lorry"alert(p2.friends);  //"Chris, Flex, Lorry"
由于friends数组存在prototype中,p1的修改会通过p2反映出来。

所以原型模式很少被单独使用。

3. 组合使用构造函数模式和原型模式

function Person(name, age, job) {       this.name = name;       this.age = age;       this.job = job;       friends : ["Chris", "Flex"];}Person.prototype = {    constructor: Person;    sayName : function(){        alert(this.name);    } };var p1 = new Person("Nicholas", 24, "Engineer");var p2 = new Person("Greg", 30, "Doctor");p1.friends.push("Lorry");alert(p1.friends);  //"Chris, Flex, Lorry"alert(p2.friends);  //"Chris, Flex"
p1修改了p1.friends属性,添加了一个新的字符串,并不影响p2.friends,它们分别引用了不同的数组。
这种混合模式是目前使用最广泛,认同度最高的创建自定义类型的方法。



0 0
原创粉丝点击