详解Javascript对象原型

1. 对象原型Prototype

1.1. 方法过载

创建一个小猫构造函数,代码如下:

function Cat(name,color){

this.name = name;

this.color = color;

 

this.run=function(){

    alert(“一只”+this.color +”的小猫飞奔过来...”);

}

this.eat=function(){

    alert(this.name +”要吃鱼”);

}

}

 

var cat1 = new Cat();

以上所有用this定义方法,this代表新的实例,都会在创建新实例时为其创建一个方法副本。

是不是有点多余,怎么解决 ??

分析:每一个类型都拥有的特性,每次在实例级别定义确实有点浪费,那么如果能在类级别定义,每一个实例自动拥有类的通用特征就好了。在这里我们就要用到prototype

1.2. 原型的使用

1.2.1. 原型属性

JavaScript中,函数本身也是一个包含了“方法”和“属性”的对象。比如之前学了一些方法(如constructor())及属性(namelength)等等。

 

现在来介绍一个新的属性--原型Prototype

 

我们创建的每个函数都有一个 prototype(原型)属性,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。 

 

// 定义一个构造器

function Person(name,age){

}

// 函数的形参个数

console.debug(Person.length)// ==>2

// 构造函数

console.debug(Person.constructor)// ==> Function()

// 原型类型

console.debug(typeof Person.prototype)// ==>object

// 原型内容

console.debug(Person.prototype)// ↓↓

spacer.gif 

每一个类(构造函数)都具有一个prototype属性,当创建这个类的实例对象原型对象的所有属性都被立即赋予要创建的对象中。

 

1.2.2. 原型操作

设值:

 

构造函数.原型.属性=属性值

构造函数.原型.方法=函数

 

取值:

   

   对象.属性

对象.方法()

 

1.2.3. 属性访问的优先级

原生属性的优先级高于原型属性。遵循从上到下查找:

spacer.gif 图片1.png

 

1.2.4. 神秘的__proto__属性

访问对象上面的属性,直接通过object.name访问。

神奇的user.__proto__属性,该属性其实就是对应User类的prototype属性。

console.debug(user.__proto__===User.prototyp);//==> true;

 

_proto_属性属于对象实例,prototype属性类的属性。

每个对象在创建后,都会自动建立一个到prototype上的引用,让对象具备类型原型的所有特征。

 

一个对象中的__proto__(prototype)属性中的成员,可以直接通过object.成员进行访问。

 

总结:每个类都有独立的prototype属性,向prototype对象上面添加属性,对象实例可以共享prototype对象上面的属性,如果对象本身已存在某个属性,使用对象本身上面的属性,如果没有则使用prototype上面的属性,如果是添加属性添加到对象上面,不影响对象的原型对象。

 

 

1.2.5. 
扩展内置对象

1.2.5.1. 扩展Array对象

我们都知道,Array对象里没有insert(插入)和remove(删除)两个方法,都是用一个splice方法完成插入、删除等操作。

// 在指定位置插入操作

Array.prototype.insert=function(index, obj){

   this.splice(index, 0, obj);

}

 

// 在指定位置删除内容

Array.prototype.remove=function(index){

   this.splice(index, 1);

}

1.2.5.2. 扩展HTMLElement对象

在新版浏览器中,所有的有DOM元素都继承于HTMLElement构造器。通过访问HTMLElement的原型,浏览器可以为我们提供扩展任意HTML节点的能力。

HTMLElement.prototype.remove = function() {

   if(this.parentNode){

          this.parentNode.removeChild(this);

   }

}


猜你喜欢

转载自blog.51cto.com/1388969/2424506