1.伪类 构造器继承
var Person = function (name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.getSaying = function () {
return this.saying || "";
}
var p = new Person("zhang");
alert(p.getName()); // zhang
var Student = function (name) {
this.name = name;
this.saying = "student saying";
}
Student.prototype = new Person();
Student.prototype.purr = function (n) {
var i, s = '';
for(i = 0; i < n; i++) {
if(s) {
s += "-";
}
s += "r";
}
return s;
}
var s = new Student("li");
alert(s.getSaying()); // sayistudent
alert(s.purr(10)); // r-r-r-r-r-r-r-r-r-r
伪类模式的本意是向面向对象靠拢,但是看起来总是格格不入,我们可以优化一个
Function.prototype.method = function (name, func) {
if (! this.prototype[name]) {
this.prototype[name] = func;
}
return this;
}
Function.method("inherits", function (Parent) {
this.prototype = new Parent();
return this;
});
var Teacher = function (name) {
this.name = name;
this.saying = "teacher saying";
}
.inherits(Person)
.method("purr", function (n) {
var i, s = '';
for(i = 0; i < n; i++) {
if(s) {
s += "-";
}
s += "r";
}
return s;
})
.method("getName", function (){
return this.getSaying() + " " + this.name + this.getSaying();
});
var t = new Teacher("wang");
alert(t.getName()); // wang
alert(t.purr(3)); // r-r-r
缺陷
没有私有环境
所有的属性都是公开的
无法访问super父类的方法
在实例化时,如果忘记new,那么this会指向全局环境
2.对象说明符
有时候,实例化构造器时会有许多参数,我们会感觉很麻烦
var myObject = maker(f, l, s, c);
因此我们可以如下面来,使用对象说明符
var myObject = maker({
first : f,
last : l,
state : s,
city : c
});
这样我们就可以很清晰的看清楚了参数的顺序关系了
对象说明符和JSON结合使用有意想不到的便捷
3.原型
让我们用对象字面量的形式创建一个有用的对象
var myPerson = {
name : "hello everyone",
getName : function() {
return this.name;
},
says : function () {
return this.saying || "";
}
}
Object.prototype.create = function (o) {
if(typeof Object.create !== "function") {
Object.create = function () {
var F = function () {};
F.prototype = o;
return new F();
}
}
}
var worker = Object.create(myPerson);
worker.name = "worker";
worker.saying = "saying";
worker.getSaying = function () {
return this.name + " " + this.saying;
}
alert(worker.getSaying()); // worker saying
alert(myPerson.getName()); // hello everyone
4.函数化
迄今为止,我们所有的继承的方式都无法保护隐私,我们可以用模式的方式来解决
var mammal = function (spec) {
var that = {};
that.getName = function () {
return spec.name;
};
that.getSaying = function () {
return spec.saying || "";
}
return that;
}
var m = mammal({name : "zhang"});
alert(m.name); // undefined
alert(m.getName()); // zhang
让cat继承mammal
Function.prototype.method = function (name, func) {
if(this.prototype[name] !== "function") {
this.prototype[name] = func;
}
return this;
}
var cat = function(spec) {
spec.saying = spec.saying || "";
var that = mammal(spec);
override getName method
that.getName = function () {
return spec.name + " : " + spec.saying;
};
that.purr = function (n) {
var i, s = '';
for(i = 0; i < n; i++) {
if(s) {
s += "-";
}
s += "r";
}
return s;
}
return that;
}
var c = cat({name : "wang", saying : "hello dear"});
alert(c.getName()); // wang : hello dear
alert(c.purr(3)); // r-r-r
// 调用父类的方法
Object.method("superior", function (name) {
var that = this,
method = that[name];
return function () {
return method.apply(that, arguments);
}
});
var littleCat = function (spec) {
var that = cat(spec);
get_super_name = that.superior("getName");
that.getName = function () {
return "like " + get_super_name() + " body";
}
return that;
}
var lc = littleCat({name : "zhangFei", saying : "Come On"});
alert(lc.getName()); // like zhangFei : Come On body
5.部件
var eventuality = function (that) {
var registry = {};
that.fire = function (event) {
// alert(event.type); // show
var array, func, handler, i,
type = typeof event === "string" ? event : event.type;
if(registry.hasOwnProperty(type)) {
array = registry[type];
// alert(array); // [object Object]
for(i = 0; i < array.length; i++) {
handler = array[i];
// alert(handler); // [object Object]
func = handler.method;
// alert(func()); // show
if (typeof func === 'string') {
func = this[func];
}
func.apply(this, handler.parameters || [event]);
}
}
return this;
}
that.on = function (type, method, parameters) {
var handler = {
method : method,
parameters : parameters
};
// handler = {
// method : "show",
// parameters : [1, 2, 3]
// }
if(registry.hasOwnProperty(type)) {
registry[type].push(handler);
} else {
registry[type] = [handler];
}
// alert(registry[type][0].method()); // show
// alert(registry[type][0].parameters); // 1, 2, 3
return this;
}
return that;
}
var e = eventuality({ name : "zhang"});
var show = function () {
return "show";
}
e.on("show", show, [1, 2, 3]);
e.fire({type : "show"});