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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值