1.偽類 構(gòu)造器繼承
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
偽類模式的本意是向面向?qū)ο罂繑n贺奠,但是看起來總是格格不入长踊,我們可以優(yōu)化一個
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
缺陷
沒有私有環(huán)境
所有的屬性都是公開的
無法訪問super父類的方法
在實例化時试吁,如果忘記new,那么this會指向全局環(huán)境
2.對象說明符
有時候谒撼,實例化構(gòu)造器時會有許多參數(shù)食寡,我們會感覺很麻煩
var myObject = maker(f, l, s, c);
因此我們可以如下面來,使用對象說明符
var myObject = maker({
first : f,
last : l,
state : s,
city : c
});
這樣我們就可以很清晰的看清楚了參數(shù)的順序關(guān)系了
對象說明符和JSON結(jié)合使用有意想不到的便捷
3.原型
讓我們用對象字面量的形式創(chuàng)建一個有用的對象
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.函數(shù)化
迄今為止廓潜,我們所有的繼承的方式都無法保護隱私抵皱,我們可以用模式的方式來解決
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
// 調(diào)用父類的方法
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"});