建立一个小猫构造函数,代码以下:浏览器
function Cat(name,color){ide this.name = name;函数 this.color = color;this
this.run=function(){spa alert(“一只”+this.color +”的小猫飞奔过来...”);prototype }debug this.eat=function(){对象 alert(this.name +”要吃鱼”);blog }继承 }
var cat1 = new Cat(); |
以上全部用this定义方法,this表明新的实例,都会在建立新实例时为其建立一个方法副本。
是否是有点多余,怎么解决 ??
分析:每个类型都拥有的特性,每次在实例级别定义确实有点浪费,那么若是能在类级别定义,每个实例自动拥有类的通用特征就行了。在这里咱们就要用到prototype。
在JavaScript中,函数自己也是一个包含了“方法”和“属性”的对象。好比以前学了一些方法(如constructor())及属性(如name和length)等等。
如今来介绍一个新的属性--原型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)// ↓↓
|
每个类(构造函数)都具备一个prototype属性,当建立这个类的实例对象原型对象的全部属性都被当即赋予要建立的对象中。
设值:
构造函数.原型.属性=属性值
构造函数.原型.方法=函数
取值:
对象.属性
对象.方法()
原生属性的优先级高于原型属性。遵循从上到下查找:
访问对象上面的属性,直接经过object.name访问。
神奇的user.__proto__属性,该属性其实就是对应User类的prototype属性。
console.debug(user.__proto__===User.prototyp);//==> true;
_proto_属性属于对象实例,prototype属性类的属性。
每一个对象在建立后,都会自动创建一个到prototype上的引用,让对象具有类型原型的全部特征。
一个对象中的__proto__(prototype)属性中的成员,能够直接经过object.成员进行访问。
总结:每一个类都有独立的prototype属性,向prototype对象上面添加属性,对象实例能够共享prototype对象上面的属性,若是对象自己已存在某个属性,使用对象自己上面的属性,若是没有则使用prototype上面的属性,若是是添加属性添加到对象上面,不影响对象的原型对象。
咱们都知道,Array对象里没有insert(插入)和remove(删除)两个方法,都是用一个splice方法完成插入、删除等操做。
// 在指定位置插入操做 Array.prototype.insert=function(index, obj){ this.splice(index, 0, obj); }
// 在指定位置删除内容 Array.prototype.remove=function(index){ this.splice(index, 1); } |
在新版浏览器中,全部的有DOM元素都继承于HTMLElement构造器。经过访问HTMLElement的原型,浏览器能够为咱们提供扩展任意HTML节点的能力。
HTMLElement.prototype.remove = function() { if(this.parentNode){ this.parentNode.removeChild(this); } } |