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

//創建類的方法 function create() { var pare " /> 国产精品国产三级国产AV麻豆,99re5久久热在线,97一期涩涩97片久久久久久久

天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

Prototype Class對象學習

復制代碼 代碼如下:
/* 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

JavaScript技術Prototype Class對象學習,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 狠狠操伊人 | 狠狠色综合7777久夜色撩人 | 纯肉巨黄H爆粗口男男分卷阅读 | 一二三四在线播放免费观看中文版视频 | 欧美jizz19性欧美 | 国产亚洲视频精彩在线播放 | 国产精品99久久免费黑人人妻 | 色偷偷男人天堂 | 精品久久久久久久久免费影院 | 国产精品久久久久久久AV下载 | 亚洲蜜桃AV永久无码精品放毛片 | 成人影院午夜久久影院 | 欧美丰满少妇久久无码精品 | 中文字幕午夜乱理片 | 好男人好资源视频高清 | 2019午夜75福利不卡片在线 | 亚洲性夜色噜噜噜网站2258KK | 人人艹人人 | 野花日本高清在线观看免费吗 | 免费在线观看的毛片 | 97视频在线观看视频最新 | 日韩精品久久日日躁夜夜躁影视 | 青苹果乐园在线观看电视剧 | 久草网国产自偷拍 | 小妇人电影免费完整观看2021 | 美女被C污黄网站免费观看 美女白虎穴 | 午夜视频无码国产在线观看 | 国产精品日本无码久久一老A | AV无码久久无遮挡国产麻豆 | 苍井空a 集在线观看网站 | 佐山爱痴汉theav | 久久精品国产免费播放 | 欧美一区二区激情视频 | 免费人成视频19674不收费 | 亚洲日韩欧美国产中文在线 | 国产超碰AV人人做人人爽 | 成年人视频在线免费观看 | 9420高清完整版在线电影免费观看 | 亚洲成 人a影院青久在线观看 | 久久热最新网站获取3 | 一本道高清到手机在线 |