2015-07-02 01:02
JS插件开发之prototype用法介绍
最近团队里面有讨论到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来写个简单的插件功能。