经常看到一些js代码里面出现类似object.prototype.ctx..等之类的代码,一直看不懂是什么意思,偶尔到网上搜了一下也觉得很模糊,今天花了大半天时间好好研究了一下,把自己心得总结一下.
prototype是一个js的函数(function)的一个属性也可以说成是它的一个对象,js默认每个类型都只能有一个原形(比如var a = new Date() 这个a的类型就是Date),默认的所有的function的原形是Object(类似于java所有的对象的父类都是object),根据我的理解,主要用途有俩种.(其他的无数,体会的主要的,请不要丢鸡蛋)
1.第一种是继承..
比如: function testParent() {
this.title = "Hello World";
}
testParent.prototype.content = "I am a java programmer";
function testSon() {
this.titleSon = "Hello World";
}
//testSon继承testParent
testSon.prototype = new testParent();
var son = new testSon();
alert(son.content);//打印的值为I am j java progranmmer;
//也可以说成 testParent是testSon的原形,可以理解为继承关系,但是不是复制,是引用,所有testSon的实例全部共享一个testParent的属性和方法.当原形(testParents)中某个原形属性( testParent.prototype.content = "I am a java programmer";),被改变时,子类(testSon)的所有实例里的content值将会改边.所以千万不要随意更改原形属性,可以用覆盖的方法,例如在子类定义一个属性或方法和父类的相同,那么就会覆盖,如果需要父类方法时,则delete(对象.属性名),可以删除子类的属性,就可以取到父类属性了. 如果需要更改testParent的原形属性则要三思,一改下面所有实例引用testParent的属性和方法全部变了,这也是prototype的缺陷所在,但是有时还是可以起到事半工倍的效果,就看用途了. 如果是自己写的testParent则没什么,直接进去修改就好了,如果是其他程序员写的还是继承以后再覆盖吧,到时还可以delete回来. 千万别在自己的子类testSon里加原形属性,这样一来也会影响testParent和所有实例. 还有一种情况就是,如果是以前的程序员写的,封装的非常的死,基本上看不到代码,并且以前的"父类"里有很多方法需要用,为了达到重用的目的,恭喜你这时候可以检测一下自己能力了,如果觉得比较强大的可以直接修改"父类"的方法或者属性,例如:testParents.prototype.content = "I am a c++ programmer";
或者如果不是很自信的话直接加新的方法或函数就好了. testParents.prototype.newContent = "good";
2.第二种用法是针对javascript里面的核心对象的,例如:Array, Date, Number.....等
除了一种叫做实例化继承法的方法可以获得核心对象的原型实例以外(这种方法也是勉强凑到一起的,实例化的对象和原型都不是同一个类型,违背了prototype的规则),其他的都不行,会报'object'; is not...
这时候可以按上面说的,直接再里面添加新的方法,也可以覆盖以前的方法.
Date.prototype.getDate = function() {alert('TMD,叫你封装')}
-_-!!
3.就是可以快速的创建1个或多个原型副本,和第一条基本类似,这里就不具体说了.
4.可以避免构造函数重读一个function里的属性.
function test(table) {
this.table = table;
this.show = function() {
alert('Hello');
}
}
这种写发,每次new一个对象都必须运行this.show..这个方法,所以可以这样改
function test(table) {
this.table = table;
}
test.prototype.show = function() {
alert('Hello world');
}
}
对性能比较好哦..