比方咱们当初的需要如下。
有一个函数MyObj,反对如下性能:
- 能够通过MyObj()的形式返回一个对象,这个对象和new MyObj()是等价的
MyObj自身是一个对象,能够通过MyObj.doit()的形式调用其上的办法或属性
为了实现需求,第一反馈是:var MyObj=function(){ return new MyObj();};
而后在MyObj上挂载静态方法,在MyObj.prototype上挂载对象办法。
看起来稳的很,其实这显著是一个死循环:
// VM160:2 Uncaught RangeError: Maximum call stack size exceededMyObj();
为了解决这个问题,咱们在MyObj的原型上定义了一个办法:
MyObj.prototype.init=function(){ return this;};
执行上面的办法:
var temp=MyObj.prototype.init();
下面返回的temp很显著就是MyObj.prototype,其实就是MyObj对象(例如:new A(),其实就是取A.prototype,这样比照就很好了解了)。
因而能够革新代码如下:
var MyObj = function (param) { return MyObj.prototype.init();};
这样MyObj和new MyObj()就别离示意类和对象。
问:看起来是不是实现了?答:是的,实现了。问:可是总感觉有点不好,说不出为什么。答:是不是感觉MyObj()打印进去的货色有点多?问:是的。
事实上,因为间接取MyObj.prototype作为new MyObj(),实践上说,应用上区别不大,惟一有余的是,挂载在MyObj.prototype上的办法会在打印MyObj对象的时候看见,不难受。
为了看起来难看些,代码再次革新:
var MyObj = function () { return new MyObj.prototype.init();};// 为了让MyObj()返回的是MyObj对象,须要批改MyObj.prototype.init的原型MyObj.prototype.init.prototype = MyObj.prototype;
此刻的原型关系变成了:
MyObj() ==return new MyObj.prototype.init() ==MyObj.prototype.init.prototype ==MyObj.prototype ==new MyObj()
此时需要就实现了,而且打印MyObj()的时候,对象上的办法都在原型上,看起来就比拟难受了。