国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

Prototype Class對象學習

2019-11-21 01:15:48
字體:
來源:轉載
供稿:網友
復制代碼 代碼如下:

/* Based on Alex Arnell's inheritance implementation. */

var Class = (function() {
//臨時存儲parent的prototype
function subclass() {};

//創建類的方法
function create() {
var parent = null, properties = $A(arguments);
    //檢查新建一個類時,是否指定了一個父對象
    //如果指定了父類,賦值給parent
if (Object.isFunction(properties[0]))
parent = properties.shift();

//真正用作返回的類,在創建實例時,將調用initialize方法進行初始化
function klass() {
this.initialize.apply(this, arguments);
}

//給klass添加addMethods方法,在調用create方法之后
    //仍可以調用addMethods方法進行類級別的方法擴充
Object.extend(klass, Class.Methods);
    //給返回的類添加兩個屬性,superclass:父類,subclasses:子類的集合
klass.superclass = parent;
klass.subclasses = [];

//如果創建類時指定了父對象,則把klass的原型指向父對象的實例,實現原型鏈繼承
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
     //為父類添加子類,維護父類的子類集合
parent.subclasses.push(klass);
}

//向新類添加方法
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);

//如果沒有指定初始化方法,則默認把一個空方法賦給初始化方法
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;

    /*
     * 修正新類的構造函數,使得構造函數指向自己,這里特意說一下(如果注釋掉下面這行):
     * var Person=Class.create();
     * var p1=new Person();
     * alert(p1.constructor==Person) //true
     * var Man=Class.create(Person)
     * var m1=new Man();
     * alert(m1.constrcutor==Man) //false
     * alert(m1.constrcutor==Person) //true
     * alert(m1.construcctor==p1.constrcutor) //true
     *
     * 看出問題來了吧?Man的構造函數竟然指向了Person的構造函數
     * 問題的根源在klass.prototype = new subclass;這句話
     * 具體原因我就不解釋了,要詳細理解的請查看《JavaScript語言精髓與編程實踐》155~160頁
    */
klass.prototype.constructor = klass;
return klass;
}

//把創建類時的方法添加到新類,或者在創建完類之后在添加類級別的方法
function addMethods(source) {
    //取得新類的父類
var ancestor = this.superclass && this.superclass.prototype;
var properties = Object.keys(source);

    //貌似下面的判斷總是為真,不知道為什么這么寫,知道的告訴我?
if (!Object.keys({ toString: true }).length) {
//如果新類重寫了toString和valueOf方法則添加之
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
properties.push("valueOf");
}

//遍歷所有的新類聲明中的方法
for (var i = 0, length = properties.length; i < length; i++) {
     //property是函數名稱,value是函數體
var property = properties[i], value = source[property];
     //判斷這個方法是否需要調用父類的同名方法
if (ancestor && Object.isFunction(value) &&
value.argumentNames().first() == "$super") {
var method = value;
        //這里很重要!
        //替換$super參數,使得這個參數指向父類的同名方法
        //這里應用了Function的wrap方法,wrap方法的解釋請參考【Prototype 學習――Function對象】
        //method是新定義的方法,所以他的第一個參數為$super,然后從'='到'.'之間返回的是父類的同名方法
        //最后調用wrap方法把$super參數替換成父類的同名方法,這樣在子類調用$super()時,將調用父類的同名方法
        //這里構造的非常棒!值得思考
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);

        //將新產生的value(即經過修改過的子類方法)的valueOf和toString指向原子類的同名方法
        //這里是在修正調用wrap方法之后的遺留問題
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
     //把方法添加到新類中
this.prototype[property] = value;
}

return this;
}

//返回Class的可調用方法
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();

這個類就提供了2個方法:create和addMethods,上面的源碼注釋中已經說明的很清楚了,下面就看些例子,具體說明一下用法:
復制代碼 代碼如下:

//聲明Person類,并定義初始化方法
var Person = Class.create({
initialize: function(name) {
this.name = name;
},
say: function(message) {
return this.name + ': ' + message;
}
});

// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
// redefine the speak method
//注意這里的$super用法,在對照源碼中的解釋仔細看一下
say: function($super, message) {
return $super(message) + ', yarr!';
}
});

var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"


復制代碼 代碼如下:

var john = new Pirate('Long John');
john.sleep();
// -> ERROR: sleep is not a method
// every person should be able to sleep, not just pirates!

//這里是addMethods的用法,可以在類級別擴充方法
Person.addMethods({
sleep: function() {
return this.say('ZzZ');
}
});
john.sleep();


復制代碼 代碼如下:

//這里是superclass和subclasses兩個屬性的用法

Person.superclass
// -> null
Person.subclasses.length
// -> 1
Person.subclasses.first() == Pirate
// -> true
Pirate.superclass == Person
// -> true

三個例子幾本覆蓋了Class類的方法,詳細例子請參考:http://prototypejs.org/learn/class-inheritance

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 涞水县| 林芝县| 南丰县| 石渠县| 蒲城县| 东兴市| 汨罗市| 白山市| 上栗县| 霍山县| 新乐市| 杨浦区| 喀喇沁旗| 金乡县| 临武县| 广丰县| 内丘县| 孟州市| 苍山县| 河北区| 旺苍县| 北票市| 枝江市| 清水县| 曲沃县| 张家界市| 县级市| 大同市| 黎川县| 抚顺市| 河西区| 堆龙德庆县| 永善县| 虞城县| 汾阳市| 长兴县| 兰州市| 巩义市| 洛川县| 澄迈县| 务川|