前言
我们知道,使用一个构造函数来创建对象时,需要使用 new
操作符。但在日常开发过程中,往往又会发现很多框架或者库(例如:jQuery、underscore)创建新对象时并没有使用 new
操作符。这样方便了大家书写代码,也显得更易读。那么,他们是怎么实现的呢?
解决方案
总的来说,这些方案都并没有很神奇的突破了 JavaScript
语法限制。而是通过一些巧妙的逻辑(共享原型、原型判断)来实现。
方案1——共享原型
1 | // 构造函数 |
上述解决方案可以看出,构造函数Class
调用时,返回了通过 new
操作符来运行 init
方法。但因为 init
的原型与 Class
的原型指向同一个对象,因此 new init()
创建出的对象拥有 Class
的原型。
方案2——原型判断
1 | var Class = function(){ |
坦白说,这个方案需要对 this
的指向理解比较深刻。当执行 Class()
时,this
为 undefined
(严格模式) 或 window
。此时,经过 if
判断后,会执行 new Class()
。再次执行时,根据 new
操作符的运行机制,this
指向的是将要创建出的对象,这个对象的原型肯定就是 Class
,因此,经过 if
判断就不会继续执行 new
, 而是向下执行构造对象的逻辑。