【Javascript 拾遗之二】prototype 原型

在开发中, 使用到一些Javascript框架, 如Jquery, Ext-js, Jquery-UI, EasyUI等,通常会看到一些开源代码中有prototype的身影。那么prototype究竟是什么呢?在oo前端开发中到底哪些应用呢?从软件工程的角度而言,能解决什么问题?接下来我们就一起来讨论一下prototype关键字在Javascript语言中的神奇之处。
 

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类函数提供了一个修改属性和方法的接口,在实例化时,这些定义的属性和方法会赋予实例化后对象,以供对象调用。

 

posted @ 2014-12-19 12:38  可爱de小野人  阅读(178)  评论(0编辑  收藏  举报