摘要:實現類的步驟第一步是使用新建類,初始化的固定函數是,不能使用其它名稱子類也是使用新建,父類在子類中,使用來繼承,與子類的方法名,同一級別子類中與父類的同名方法,如果需要在父類的同名方法上拓展,需要在子類的同名方法內,使用如果需要在類的外面增
實現類的步驟
第一步是使用new Class新建類,初始化的固定函數是initialize,不能使用其它名稱
子類也是使用new Class新建,父類在子類中,使用Extends:parentClass來繼承,Extends與子類的方法名,同一級別
子類中與父類的同名方法,如果需要在父類的同名方法上拓展,需要在子類的同名方法內,使用this.parent(args)
如果需要在類的外面增加方法,可以使用implement方法
// 使用 Class.create 創建類 var Person = new Class({ // 初始函數固定為 initialize, initialize:function(name) { this.name = name; this.friends = ["jack", "mark"]; }, getName: function(){ console.log("My name is " + this.name); }, setFriends:function(friend){ this.friends.push(friend); }, getFriends:function(){ console.log(this.friends) } }); // 使用 implement 給類添加方法,子類可以繼承該方法 Person.implement({ getAge:function(age){ console.log("My age is " + age); } }) // 子類通過 new Class 創建類 var Chinese = new Class({ // 子類通過 Extends 來繼承父類 Extends:Person, initialize:function(name, addr){ this.parent(name); this.addr = addr; }, getAddr:function(){ console.log("My address is " + this.addr); } }); var Japanese = new Class({ Extends:Person, initialize:function(name){ this.parent(name); } }) // 實例化類 var men = new Chinese("allen", "BeiJing"); men.getName(); // My name is allen men.getAge(23); // My age is 23 men.getAddr(); // My address is BeiJing // 以下驗證 - 子類繼承父類的屬性,修改了之后,其他子類再次繼承父類,父類的屬性的值為何不會改變 var allen = new Person(); allen.getFriends(); // ["jack", "mark"] var women = new Japanese(); women.setFriends("lisa"); women.getFriends(); // ["jack", "mark", "lisa"] var men = new Chinese(); men.setFriends("peter"); men.getFriends(); //["jack", "mark", "peter"] var wallen = new Person(); wallen.getFriends(); //["jack", "mark"]
JS是如何實現類的方法,有幾個重要的問題需要搞清楚
JS是如何創建類的
子類是如何實現繼承父類屬性和方法的
子類繼承父類的屬性,修改了之后,其他子類再次繼承父類,父類的屬性的值為何不會改變
子類和父類的同名函數,使用this.parent(args)在函數中使用,是如何做到在子類中的同名函數共存的
如何實現,不在類中,而是使用implement往類中添加方法的
下面來通過Mootools.js的class來具體分析
(function(){ // 新建一個 Class 的類,new Type 也是一個函數 var Class = this.Class = new Type("Class", function(params){ // 如果傳入的 參數是方法,就把該函數當作初始化的方法 if (instanceOf(params, Function)) params = {initialize: params}; var newClass = function(){ // 解除屬性里對其他對象的引用 reset(this); // 如果當前類正在構建,就返回當前類,不做任何操作 if (newClass.$prototyping) return this; // $caller 和 $family 是什么啊 this.$caller = null; this.$family = null; // 有初始化函數的話,就傳入參數到該初始化函數,沒有就返回自身 var value = (this.initialize) ? this.initialize.apply(this, arguments) : this; // 這句又是什么意思,一個 $caller ,一個 caller this.$caller = this.caller = null; return value; // extend(this) 把類的方法,都添加到當前新建的類中 // implement(params) 把 params 的所有方法都添加到當前類中 }.extend(this).implement(params); //指定 constructor ,以便使用 instanceOf 來驗證 newClass.$constructor = Class; newClass.prototype.$constructor = newClass; // 指定當前類的父類是哪一個 newClass.prototype.parent = parent; return newClass; }); /* 在子類擁有和父類同名方法時,使用 this.parent(args) 方法來調用父類的該方法 */ var parent = function(){ // :: 如果當前方法沒有被調用,那么就說,parent 方法沒有被調用 if (!this.$caller) throw new Error("The method "parent" cannot be called."); // 當前函數被調用的名字 function person(age) { this.age = age },則 age 被調用的就是 person 函數,就是得到 person 這個名字 var name = this.$caller.$name, // $owner 當前類對象, 得到當前類對象的父類對象 parent = this.$caller.$owner.parent, // 得到父類相同名字的方法 previous = (parent) ? parent.prototype[name] : null; if (!previous) throw new Error("The method "" + name + "" has no parent."); // 父類的該同名函數,添加到當前子類中 return previous.apply(this, arguments); }; // 解除屬性里對其他對象的引用 // 這個解除的例子,可以看 http://hmking.blog.51cto.com/3135992/675856 var reset = function(object){ for (var key in object){ var value = object[key]; switch (typeOf(value)){ case "object": var F = function(){}; F.prototype = value; object[key] = reset(new F); break; case "array": object[key] = value.clone(); break; } } return object; }; var wrap = function(self, key, method){ if (method.$origin) method = method.$origin; var wrapper = function(){ // 如果方法是是被保護的,或者這個方法沒有 caller ,就不能被調用 if (method.$protected && this.$caller == null) throw new Error("The method "" + key + "" cannot be called."); var caller = this.caller, current = this.$caller; this.caller = current; this.$caller = wrapper; // 將 method 綁定到當前對象中 var result = method.apply(this, arguments); this.$caller = current; this.caller = caller; return result; // 通過extend ,把當前函數的屬性附加到 self 里去 }.extend({$owner: self, $origin: method, $name: key}); return wrapper; }; var implement = function(key, value, retain){ // Mutators 的 key 只有 Extends 和 Implements if (Class.Mutators.hasOwnProperty(key)){ value = Class.Mutators[key].call(this, value); if (value == null) return this; } if (typeOf(value) == "function"){ // 隱藏的方法子類就不要再繼承使用了 // $hidden 和 $protected 去看函數那章 if (value.$hidden) return this; this.prototype[key] = (retain) ? value : wrap(this, key, value); } else { // merge 應該是同名的函數,這樣就直接添加進去就好 Object.merge(this.prototype, key, value); } return this; }; // 為了將父類的的屬性繼承到子類,會使用中間變量,將父類傳遞給中間變量,再通過中間變量傳遞給子類 var getInstance = function(klass){ // 誰知當前當前類正在構建 klass.$prototyping = true; var proto = new klass; // 這里就刪除 $prototyping ,也就是構建的過程就是上面這一行咯 delete klass.$prototyping; return proto; }; // 這里有 overloadSetter ,所以,可能是 Class.implement 方法,來給類額外添加函數的 Class.implement("implement", implement.overloadSetter()); Class.Mutators = { // 傳給 extends 的參數是 parent Extends: function(parent){ // 指向當前類的父類是 parent 參數 this.parent = parent; // 使用 getInstance 得到父類的全部方法 this.prototype = getInstance(parent); }, Implements: function(items){ Array.convert(items).each(function(item){ var instance = new item; for (var key in instance) implement.call(this, key, instance[key], true); }, this); } }; })(); /* Extends 其實是分兩部分,使用 Extends 的時候,是把父類的所有屬性和方法,通過 getInstance 來附加到當前類中 然后當前類的方法中,可以使用 this.parent(args) 方法,來把父類的同名方法加載進來 Implements 方法中沒有指代 this.parent = parent ,所以如果當前類寫了和父類同名的方法,就會覆蓋父類的方法 Implements 只是給當前類添加更多的方法 */
JS面向對象系列
《javascript高級程序設計》 繼承實現方式
prototype.js 是如何實現JS的類以及類的相關屬性和作用
klass 是如何實現JS的類以及類的相關屬性和作用
總結:prototype.js,Mootools.js和klass.js 實現類的方法的異同與優劣
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/84523.html
摘要:構建類的方法使用來構建類使用來構建類使用來構建類繼承父類的方法使用子類方法構建子類,繼承父類,在與父類同名的方法中,第一個參數為,方法體內使用來拓展父類的同名方法使用正常構建類后,第一個方法使用來繼承父類,在子類的方法體中,使用來拓展父類的 構建類的方法 Prototype.js使用Class.create來構建類 Mootools.js使用new Class來構建類 klass.j...
摘要:前面介紹了和是如何實現類,及其類的屬性和作用的。今天介紹的就是單純的實現面向對象的庫,只有多行,也照例分析吧。 前面介紹了prototype.js和Mootools.js是如何實現類,及其類的屬性和作用的。今天介紹的klass.js就是單純的實現面向對象的庫,只有90多行,也照例分析吧。 實現類的步驟 第一步是使用klass新建類,初始化的固定函數是initialize,不能使用其它...
摘要:實現類的步驟第一步是使用新建類,初始化的固定函數是,不能使用其它名稱子類也是使用新建,父類放在第一個參數中,如子類中與父類的同名方法,如果需要在父類的同名方法上拓展,在需要在第一個參數中使用,然后在方法體內使用如果需要在類的外面增加方法,可 實現類的步驟 第一步是使用Class.create新建類,初始化的固定函數是initialize,不能使用其它名稱 子類也是使用Class.cr...
摘要:寄生式繼承的思路與寄生構造函數和工廠模式類似,即創建一個僅用于封裝繼承過程的函數,該函數在內部已某種方式來增強對象,最后再像真的是它做了所有工作一樣返回對象。 這篇本來應該是作為寫JS 面向對象的前奏,只是作為《javascript高級程序設計》繼承一章的筆記 原型鏈 code 實現 function SuperType() { this.colors = [red,blu...
TCP/IP HTTP和HTTPS有何區別? httpbin 一個簡單的HTTP請求和響應服務。 TCP的三次握手與四次揮手 通俗易懂版,詳細版本 MySQL CHAR和VARCHAR存取的差別 《高性能MySQL》筆記 - MySQL 鎖的基本類型 MySQL中的鎖之一:鎖的必要性及分類 MySQL中的鎖之二:行鎖、頁鎖、表鎖 MySQL Like與Regexp的區別 數據結構 數...
閱讀 2028·2021-10-09 09:41
閱讀 1602·2021-09-28 09:36
閱讀 1105·2021-09-26 09:55
閱讀 1295·2021-09-10 11:17
閱讀 1149·2021-09-02 09:56
閱讀 2764·2019-08-30 12:58
閱讀 2937·2019-08-29 13:03
閱讀 1856·2019-08-26 13:40