2015-07-02 01:02

JS插件开发之prototype用法介绍

码仔Z 2004 7

最近团队里面有讨论到js插件的写法,自然就讨论到了prototype的用法,整理之后在这里做下简单的分享,内容比较简单,欢迎吐槽,js大咖们可以略过~


prototype是在IE4及其以后版本引入的一个针对于某一类的对象的方法,当你用prototype编写一个类后,如果new一个新的对象,浏览器会自动把prototype中的内容替你附加在对象上。这样,通过利用prototype就可以在JavaScript中实现成员函数的定义,甚至是“继承”的效果。


prototype属性算是JavaScript与其他面向对象语言的一大不同之处,不同在于prototype是“一个给类的对象添加方法的方法”,使用prototype属性,可以给类动态地添加方法,如不理解,别急,稍等我们通过一些简单的例子做下讲解。


首先,我们要先了解一下“类”的概念,JavaScript本身是一种面向对象的语言,它所涉及的元素根据其属性的不同都依附于某一个特定的类。我们所常见的类包括:数组变量(Array)、逻辑变量(Boolean)、日期变量(Date)、结构变量(Function)、数值变量(Number)、对象变量(Object)、字符串变量(String) 等,而相关的类的方法,也是程序员经常用到的,例如数组的push方法、日期的get系列方法、字符串的split方法等等,但是在实际的编程过程中不知道有没有感觉到现有方法的不足?prototype 方法应运而生!下面,将通过实例由浅入深讲解prototype的具体使用方法:


1、最简单的例子,了解 prototype:

Number.add(num):作用,数字相加

Number.prototype.add = function(num){return(this+num);}
alert((3).add(5));//输出 8


2、已有方法的实现和增强,初识 prototype:

Array.push(new_element):作用,在数组末尾加入一个新的元素

Array.prototype.push = function(new_element){
    this[this.length]=new_element;
    return this.length;
}

让我们进一步来增强他,让他可以一次增加多个元素!

实现方法:

Array.prototype.pushPro = function() {
    var currentLength = this.length;
    for (var i = 0; i < arguments.length; i++) {
        this[currentLength + i] = arguments[i];
    }
    return this.length;
}
var a=new Array(3,4);
a.pushPro(6,7,8);
alert(a.length + "\n" +a[4]);//输出 5  8

应该不难看懂吧?以此类推,你可以考虑一下如何通过增强 Array.pop 来实现删除任意位置,任意多个元素(这里不再细说,有兴趣的同学可以自己去试试)。


到这里,是不是对prototype是“一个给类的对象添加方法的方法”有了进一步的理解,继续往下看:


我们可以在类型上使用proptotype来为类型添加行为。这些行为只能在类型的实例上体现(可以这样分,没有实例化的类称为类型,实例化的类称为对象实例简称实例)。看代码:

<script type="text/javascript">
    //1
    Object.prototype.name = "zhangsan";
    Object.prototype.Method1 = function(){
    	alert(this.name);
    }
    var obj = new Object();
    obj.Method1();// 输出 zhangsan
    alert(obj.name);// 输出 zhangsan
    
    //2、在实例上不能使用prototype,否则会发生编译错误
    obj.prototype.sex = "男";//error,无法给一个实例prototype
    var o = {name:"lisi"}
    o.prototype.age = 30;//error,无法给一个实例prototype

    //3、定义静态属性、方法,直接在类型上调用即可
	Object.name2="lisi";
	Object.Method2=function(){alert("1");}
	alert(Object.name2);//输出lisi
	Object.Method2();//输出 1
	//实例不能调用类型的静态属性或方法,否则发生对象未定义的错误。
	var obj = new Object();
	obj.Method2();//error

        //可以在外部使用prototype为自定义的类型添加属性和方法。
    function Mytest(){
        this.name = "zhangsan";
      this.age = 20;
    }
    Mytest.prototype.hello = function(){
      alert(this.name);
    }
    var m = new Mytest();
    m.hello();// 输出 zhangsan
		
	//在外部不能通过prototype改变自定义类型的属性或方法。
    //该例子可以看到:调用的属性和方法仍是最初定义的结果。
    Mytest.prototype.name = "lisi";     
    var mm = new Mytest();      
    alert(mm.name);// 输出 zhangsan
	
	//可以在对象实例上改变或增加属性。
    //也可以在对象上改变或增加方法。
    mm.name2 = "lisi";
    mm.hello = function(){
      alert(this.name2);
    }
	mm.hello();// 输出 lisi
	
	//继承,这个例子说明了一个类型如何从另一个类型继承。
    function Mytest2(){}
    Mytest2.prototype = new Mytest;
    var m2 = new Mytest2();
    alert(m2.name);// 输出 zhangsan

	//这个例子说明了子类如何重写父类的属性或方法。
    Mytest2.prototype.name = "wangwu";
    Mytest2.prototype.hello = function(){
       alert('mytest2 hello');
    }
    var m3 = new Mytest2();
	alert(m3.name);// 输出 wangwu
    m3.hello();// 输出 mytest2 hello
 
    //子类中的name属性值不会被父类覆盖(子类重写父类的属性或方法)
    function Mytest3(){
       this.name = "子类";
       this.age = 30;
    }
    Mytest3.prototype = new Mytest();
    var m4 = new Mytest3();
    alert(m4.name);//输出 子类
</script>


讲了这么多,大家可能会问,prototype有什么用处,他有什么优点?看下面代码:

function user(name){
	alert("姓名:"+name+",年龄:"+this.age+",性别:"+this.sex);
}
user.prototype.age=20;
user.prototype.sex="男";
new u1("zhangsan");//输出:姓名:zhangsan,年龄:20,性别:男
new u2("lisi");//输出:姓名:lisi,年龄:20,性别:男

看完这个例子大家应该明白了,使用prototype既能保留公有性,又能具有私有性。


OK,prototype的基本用法就简单介绍到这里,下一篇我们将运用prototype来写个简单的插件功能。

7

© Copyright 2024. All right reserved. Powered by UDC   闽ICP备2021012238号-1     闽公网安备 35020302034854号