【Javascript 拾遗之二】prototype 原型
prototype 原型
1、定义
Javascript中有两种容易混淆的类型, function 和 object, 有很多朋友认为他们是一种类型,或是无法分清。我们先来看一下什么时候是function什么时候是object。
var fun1 = function(){ alert('prototype'); } alert(typeof fun1); // function var fun1O = new fun1(); // prototype alert(typeof fun1O); // object
一个函数声明好之后他只是在静态内存中,它的类型是function的,使用new 关键字后,function就转换成了object类型,只有对象可以调用其中的方法和属性。
接下来我们来看一下prototype的定义和用法:
prototype其实就是function对象下的一个默认属性,它可以指向一个对象,在实例化这个类(Javacript严格说没有类,但你可以函数看做是一个简单的类)后,这个对象的方法和属性都可被调用。我们称指向的这个对象叫做原型对象。
function People(name) { // People.prototype.name = 'xxx' console.warn(People.prototype); } console.warn(People); console.warn(People.prototype); People.prototype = { name : 'aaa', method : function(){ return ("My name is aaa!"); } } var o = new People(); console.warn(o.name); console.warn(o.method()); //People(name) 是一个简单的函数 //People {} 通过New关键字后,是一个对象 //Object { name="aaa", method=function()} 原型对象 //aaa 调用对象属性 //My name is aaa! 调用对象方法
对象内部prototype的结构是这样的:
window.People.prototype = {
name : 'aaa',
method : function(){
...
}
}
****15/1/15修订另外,在prototype对象中还默认有一个constructor属性,这个属性指向函数本身,即是构造函数,这个构造函数不能传任何参数,只能调用不带参数的匿名函数。
实例化前,调用方法 var fun = function(){}; fun.prototype.constructor();fun.prototype.constructor.call(this):
实例化后,调用方法 var obj = new Object(); obj.constructor();obj.constructor.call(this):
-调用构造函数
1 var a = function(){ 2 return 123; 3 } 4 console.warn(a.prototype.constructor.call(this));//123 5 console.warn(a.prototype.constructor());//123 6 7 var b = new function(){ 8 return 456; 9 } 10 console.warn(b.constructor.call(this));//456 11 console.warn(b.constructor());//456
-判断对象的原型
constructor 属性同样可用来判断对象是不是“类”的一个实例。和instanceof一样。
1 var a = function(){ 2 return 123; 3 } 4 var b = new a(); 5 console.log(b.constructor === a); // true 6 console.log(b instanceof a); // true
2、应用
-原型函数扩展
通常我们想扩展一个Javascript标准对象的方法可以用这样的方法:(ex.给数组添加一个in_array()的方法,判断某个值是否在这个数组中)
这样的调用Array.prototype.in_array,我们发现Array也是一个函数,或者你可以把它看成一个‘类’,我们通过prototype这个属性添加了它的一个源生方法。
如果修改Array.prototype.push,那么将会修改Array默认的push方法,这样做是不建议的。
Array.prototype.in_array = function(e) { for (var i = 0, l = this.length; i < l && this[i] != e; i++) ; return !(i == this.length); }
console.warn([1,2,3,4,5],in_array(3));
//true
-继承
一个简单的A集成B的例子。这种继承方法比较old style了,现在流行的框架中一般都使用对象字面量的属性复制和拷贝,很少用这种方式,因为这种方式效率比较低。在此只做了解和学习。
var A = function(){} var B = function(){ return { name : 'b', method : function(){ alert('I\'m b'); } } } A.prototype = new B(); var a = new A(); alert(a.name); a.method();
3、总结
本文简单地介绍了prototype属性的定义和用法,其实也不用把它想得非常深奥和复杂,想想JAVA或是C++中的构造函数,就很容易明白它的用途了,说明白点prototype就是为Javascript类函数提供了一个修改属性和方法的接口,在实例化时,这些定义的属性和方法会赋予实例化后对象,以供对象调用。