构造器调用模式
当一个函数对象被创建时,Function 构造器会运行类似这样的代码:
this.prototype = {constructor: this}
new 一个函数事会发生:
Function.method('new', function() {
// 创建新对象,继承原型
let that = Object.create(this.prototype);
// 调用构造函数,绑定 this 到新对象
let res = this.apply(that, arguments);
return typeof res === 'object' && res || that;
});
伪类继承
let Mammal = function(name) {this.name = name;}
Mammal.prototype.get_name = function() {return this.name;}
// 构造一个实例
let myMammal = new Mammal('zhangsan');
// 利用伪类继承 Mammal
let Cat = function(name) {
this.name = name;
this.age = age;
}
Cat.prototype = new Mammal();
Cat.prototype.get_age = function() {return this.age;}
let myCat = new Cat('miao');
以上就是一个简单的伪类继承。使用构造器有个严重的危害,如果在调用构造器函数的时候忘记使用 new 前缀,this 不仅不会绑定到新对象,还会污染全局变量;
原型模式
原型模式中,我们采用对象来继承。
let myMammal = {
name: 'aa',
age: 22,
get_name: function() {return this.name;}
}
let myCat = Object.create(myMammal);
Cat.get_age = function() {return this.age;}
这种继承方式,导致没有私有属性和私有函数
函数化模式
它的每一层都是在扩充 that
Function.prototype.method = function (name,func) {this.prototype[name] = func;
return this;
}
// 工厂 mammal 函数
var mammal = function (spec) {var that = {};
that.get_name = function () {return spec.name;}
that.says = function (spec) {return spec.saying || '';}
return that;
}
// 工厂 cat 函数 (基于 mammal 的函数)
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
// 直接调用 mammal 函数
var that = mammal(spec);
that.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {if(s) {s += '-';}
s += 'r';
}
}
that.get_name = function () {return that.says() + '' + spec.name +' ' + that.says();}
return that;
}
// 创建 myCat 对象
var myCat = cat({name: 'Henrietta'});
Object.method('superior',function (name) {
var that = this,
method = that[name];
return function () {return method.apply(that, arguments)
}
})
// 工厂 coolcat 函数 (基于 cat 函数)
var coolcat = function (spec) {var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function (n) {return 'like' + super_get_name() + 'baby';
}
return that;
}
var myCoolCat = coolcat({name : 'Bix'});
var name = myCoolCat.get_name();
部件
没看懂。。
let eventuality = function(that) {let registry = {};
that.fire = function(event) {
let array,
func,
handler,
i,
type = typeof event === 'string' ? event : event.type;
if (registry.hasOwnProperty(type)) {array = registry[type];
for(i = 0; i < array.length; i++) {handler = array[i];
func = handler.method;
if (typeof func === 'string') {func = this[func];
}
func.apply(this, handler.parameters || [events]);
}
}
return this;
}
that.on = function(type, method, parameters) {
let handler= {
method,
parameters
};
if (registry.hasOwnProperty(type)) {registry[type].push(handler);
} else {registry[type] = [handler];
}
return this;
}
return that;
}