前提:
使用 JS 创建对象的最优办法,是 原型模式。
step1: 原型模式的基础使用方式
function fn(){}
fn.prototype = {}
var x = new fn();
x.aaa();
缺点:使用 fn.prototype 中的成员时,需要先创建 fn的实例:var x = new fn();
麻烦,希望不需要每次都实例化。
尝试1: 让 fn()返回 fn的实例,即返回 new fn();
function fn(){
return new fn();
}
结果:死循环.
分析:希望返回 实例的原因是因为 希望通过实例访问定义在原型中的方法。
但是:访问呢定义在原型中的方法,不仅仅可以通过实例,还可以 直接返回原型对象。
尝试2: 让 fn()返回 fn.prototype,即返回 自己的原型。
function fn(){
return fn.prototype;
}
下面一步想不到,假设 jquery的作者跳跃到使用这一步。
直接返回 fn.prototype 也可以使用另外一种方式实现:
1 在 fn.prototype 中定义一个方法, init()
2 在 init() 中返回 this:this指向 fn.prototype
3 在 fn() 中返回 fn.prototype.init();
function fn(){
return fn.prototype.init();
}
fn.prototype = {
init:function(){
return this;
}
}
结果:可以访问 定义在 fn.prototype中的成员。但是不仅仅可以访问,还可以修改。
我们不允许修改定义在 fn.prototype 中的方法。
解决:使用new 运算符.
规则:new 可以使得实例只能读取其构造函数prototype但是无法修改。
function fn(){
return new fn.prototype.init();
}
fn.prototype = {
init:function(){
return this;
}
}
问题:当前返回的 实例是 init()的实例,但是所有的成员都是定义在 fn.prototype 上面。
所以需要让 init.prototype 指向 fn.prototype:
fn.prototype.init.prototype = fn.prototype;
将所有的代码放到独立命名空间中.
(function(){
function fn(){
return new fn.prototype.init();
}
fn.prototype = {
constructor:fn,
init:function(){}
}
fn.prototype.init.prototype = fn.prototype;
window._ = fn;
})();