1.prototype(原型)
在JavaScript中,我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是保存某些可以被特定类型的所有实例所共享的属性或者方法。也就是说,当我们给某个函数Person的prototype增加属性或方法时,以Person为构造函数生成的所有实例都能访问到该属性或方法:
<script type="text/javascript"> //定义Person方法并创建两个Person实例 function Person(){} var person1 = new Person(); var person2 = new Person(); //为Person的原型增加name属性和sayName方法 //即使在实例的创建之后定义,但对实例也是立即可见的 Person.prototype.name = "Peter"; Person.prototype.sayName = function(){return this.name;}; //所有实例共享原型上的属性或者方法 alert(person1.name); //Peter alert(person2.name); //Peter alert(person1.sayName()); //Peter alert(person2.sayName()); //Peter //当实例中有同名的变量或者方法时,prototype的属性或者方法则被隐藏了(并非覆盖) person1.name="Billy"; alert(person1.name); //Billy delete person1.name; alert(person1.name); //Perter //使用hasOwnProperty()可以判断某个属性是否为自有属性 alert(person1.hasOwnProperty("name"));//false person1.name="Jack"; alert(person1.hasOwnProperty("name"));//false </script>
2.原型、构造函数和实例之间的关系
当我们定义一个函数的时候,它的默认的prototype对象便随之产生,这个prototype对象有一个construtor属性指向该函数,而使用该函数创建的所有实例内部都含有一个指针__proto__指向prototype对象(IE8中不能访问该指针):
<script type="text/javascript"> function Person(){} alert(Person.prototype); //[object Object] //prototype的constructor属性指向Person alert(Person.prototype.constructor); //function Person(){} alert(Person.prototype.constructor == Person);//true //每个实例存在一个__proto__指针指向Person.prototype //IE中不能访问 var person = new Person(); alert(person.__proto__); //[object Object] alert(person.__proto__==Person.prototype); //true(IE为false) </script>
3.原型链与继承
一个prototype是一个对象,因此,它必然有一个__proto__指针指向构造函数的prototype对象,同样道理,这个prototype对象又有一个__proto__指针指向构造函数的prototype对象,这样一环接一环直到Object.prototype,这就组成了一条原型链。当我们调用某个实例的属性或者方法的时候,首先从该实例寻找该变量或者方法,若找到则返回;否则寻找__proto__所指向的prototype对象,若还是没找到则继续寻找其__proto__指向的对象,直到找到或者到达原型链的末尾为止。我们可以通过这种查找方式实现继承。
function SuperType(name) { this.name = name; } SuperType.prototype.sayName = function(){ alert(this.name); }; function SubType(name, age) { SuperType.call(this, name); this.age = age; } SubType.prototype = new SuperType(); SubType.prototype.sayAge = function() { alert(this.age); };