js关于原型构造函数和原型链的理解

js的面向对象方式的函数有很多种方式,其中有两个比较重要的是两种方式一是构造函数模式,一是原型模式。

1、构造函数模式如:

function Persion(name,age) {   
   this.name = name;
   this.age= age;
   this.sayName = function() {
        alert(this.name);
   }
}
var person1 = new Person("Alex",29);
person1.sayName(); //"Alex"

var person2 = new Person("XiaoMing", 28);
person2.sayName(); //"XiaoMing"


要创建一个Person的实例,大致分为几步:

1) 使用new创建一个新对象

2)将构造函数的作用域赋给新对象(this指向当前对象)

3)执行构造函数中的代码

4)返回新对象


优点:结构简单

缺点:每个方法都要在每个实例上创建一遍

2、原型模式如:

每个函数都有一个prototype属性,即原型属性,它是一个指针,指向的是一个可以供函数的实例共享属性和方法的的对象。

function Persion(name,age) {
       
}

Person.prototype.name = "Alex";
Person.prototype.age= 29;
Person.prototype.sayName = function() {
           alert(this.name);
}

var person1 = new Person();
person1.sayName();  //"Alex"

var person2 = new Person();
person2.sayName();  //"Alex"

       创建一个函数就会有一个prototype的属性,指向一个原型对象。而原型对象会有一个constructor的属性,包含一个指针,又指向了prototype所在的函数。如:

js关于原型构造函数和原型链的理解_第1张图片

因此,基于Person的两个实例对象都共享了Person的原型对象的属性和方法,因为他们指向了同一个对象。

实例在调用属性的时候首先会在自己的实例中去搜寻,如果没有找到则继续去原型对象中搜寻。所以我们给一个实例增加一个属性或者方法时,这个属性或方法会屏蔽原型对象中同名的属性或者方法。

原型的另一种简单写法:

function Person() {
}
Person.prototype = {
   constructor:Person,
   name:"Alex",
   age:29,
   sayName: function() {
        alert(this.name);
   }
}

此方法相当于重写了原型对象,特别需要注意增加constructor属性。

优点:可以让所有实例共享属性和方法

缺点:优点也是缺点,当实例操作某一个属性值时,别的实例因为访问的是同一个原型对象,所以取到的是变化后的值。


3、组合使用构造模式和原型模式

构造函数模式用于实例的属性,原型模式用于方法和共享的属性。这样,每个实例有一份实例属性的副本,同时共享方法的引用。

function Person(name,age) {
   this.name = name;
   this.age = age;
}
Person.prototype = {
   constructor:Person,
   sayName: function() {
        alert(this.name);
   }
}

var person1 = new Person("Alex",29);
var person2 = new Person("Xiaoming",28);

person1.sayName();//"Alex";
person2.sayName();//"Xiaoming"








你可能感兴趣的:(js)