js高级教程 第六章-面对对象的程序设计(二)

(接上一节)

  • 原型的动态性
function Person(){}
var person = new Person();
Person.prototype.sayHi = function(){
  alert('Hi');
}

person.sayHi();//Hi

在这里,我们是先声明的一个person实例,然后在对Person进行地修改,但是结果确实例可以获取属性。因为实例和原型之间是松散链接的,不过是指针。
person会先在实例中搜索,如果没有就在原型中搜索。
所以可以所示对原型进行添加操作,并且可以立即在实例中反应出来。

但是如果我们重写原型对象结果就不一样了。

function Person(){}
var person = new Person();
Person.prototype = {
  constructor : Person,
  name : 'an',
  age : 12,
};

alert(person.name);//undefined

因为重写会导致新的构造函数。而先创建实例的时候的构造函数和现在的构造函数(实际上就是指针)已经不一样了。旧的构造函数指向的不是新的。

  • 原生对象的原型

哪些是原生对象:

Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError、ActiveXObject(服务器方面)、Enumerator(集合遍历类)、RegExp(正则表达式)

前面我们知道,通过原型可以添加修改属性,这对于原生对象的原型也是可行的。

String.prototype.startwith = function(text){
  return this.indexOf(text) == 0
}

var msg = 'Hi man';
alert(msg.startwith("Hi")); //true

在原生对象Sring中定义了一个新函数startwith,用来返回一个布尔值(text首次出现的位置是不是文本的起始位置),结果为true。

PS:不建议这么做,不建议修改原生对象的原型。

  • 原型对象的问题
    1.就是所有的实例默认下都是相同的属性。
    2.是实力共享(对于函数这是可行的,对于基本类型也是可行的,可以覆盖嘛),但是对于引用类型结果就大不一样了。

function Person(){
}
Person.prototype = {
  name : ['li','zhang']
}

var person1 = new Person();
var person2 = new Person();

person1.name.push('han');

alert(person1.name);//li zhang han
alert(person2.name);//li zhang han

如上面的代码,我们的本意是在person1这个实例中存储新添加的名字,但是属性的共享使得person2也可以获得这个名字。

  • 组合使用构造函数模式和原型模式
    为了解决上面的模式的问题,于是有了这种混杂模式,获得了构造函数可以产生实例属性和原型模式可以产生共享属性的优势。(happy!)
//构造函数模式
function Person(name,age,job){
          this.name=name;
          this.age=age;
          this.job=job;
          this.friends=["shelby","Court"];
}
//原型模式 
Person.prototype={
        contructor:Person,
        sayName:function(){
             alert(this.name);
   }
}
var person1=new Person("Nicholas",29,"Engineer");
var person2=new Person("Greg",27,"Doctor");

person1.friends.push('van');
alert(person1.friends);//Shely,Count,Van;
alert(person2.friends);//Shely,Count;
alert(person1.friends===person2.friedns);//false;
alert(person1.sayName===person2.sayName);//true;

可以看到,perosn1含有自己的实例,在friends中的van是person1独有的。

  • 动态原型模式
    动态原型模式的优势是不需要独立的构造函数和原型,而是把信息都封装在构造函数中,可以通过在构造函数中初始化原型(如果必要的话)。
function Person(name,age,job){
          this.name=name;
          this.age=age;
          this.job=job;
          this.friends=["shelby","Court"];

        Person.prototype.sayName = function(){
          alert(this.name);
        }


}

var person = new Person('li',21,'doctor');
person.sayName();//li

(下一节将从‘寄生构造函数模式开始’)
原文地址:https://www.cnblogs.com/comefuture/p/8305950.html