摘要:前面介紹了和是如何實現(xiàn)類,及其類的屬性和作用的。今天介紹的就是單純的實現(xiàn)面向對象的庫,只有多行,也照例分析吧。
前面介紹了prototype.js和Mootools.js是如何實現(xiàn)類,及其類的屬性和作用的。今天介紹的klass.js就是單純的實現(xiàn)面向對象的庫,只有90多行,也照例分析吧。
實現(xiàn)類的步驟
第一步是使用klass新建類,初始化的固定函數(shù)是initialize,不能使用其它名稱
子類使用ParentClassName.extend{// 子類方法}繼承
子類中與父類的同名方法,如果需要在父類的同名方法上拓展,需要在子類的方法體中使用this.supr(args)
如果需要在類的外面增加方法,可以使用methods方法
// 使用 klass 創(chuàng)建類 var Person = klass({ // 初始函數(shù)固定為 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) } }); // 使用 methods 給類添加方法,子類可以繼承該方法 Person.methods({ getAge:function(age){ console.log("My age is " + age); } }) // 子類直接通過 ParentClassName.extend 來繼承父類 var Chinese = Person.extend({ initialize:function(name, addr){ // 使用 this.supr(args)來使用父類的同名函數(shù) this.supr(name); this.addr = addr; }, getAddr:function(){ console.log("My address is " + this.addr); } }); // 子類直接通過 ParentClassName.extend 來繼承父類 var Japanese = Person.extend({ initialize:function(name){ this.supr(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是如何實現(xiàn)類的方法,有幾個重要的問題需要搞清楚
JS是如何創(chuàng)建類的
子類是如何實現(xiàn)繼承父類屬性和方法的
子類繼承父類的屬性,修改了之后,其他子類再次繼承父類,父類的屬性的值為何不會改變
子類和父類的同名函數(shù),在同名函數(shù)中使用$supr,是如何做到在子類中共存的
如何實現(xiàn),不在類中,而是使用methods往類中添加方法的
下面來通過klass.js來具體分析
!function (name, context, definition) { if (typeof define == "function") define(definition) else if (typeof module != "undefined") module.exports = definition() else context[name] = definition() }("klass", this, function () { var context = this , f = "function" // 是否使用了 supr 來調(diào)用父類的同名函數(shù) , fnTest = /xyz/.test(function () {xyz}) ? /supr/ : /.*/ , proto = "prototype" // o 為創(chuàng)建類時,類的方法 function klass(o) { return extend.call(isFn(o) ? o : function () {}, o, 1) } // 判斷對象是否是函數(shù) function isFn(o) { return typeof o === f } // 將父類的方法/屬性,附加到子類中 function wrap(k, fn, supr) { return function () { var tmp = this.supr // 當前函數(shù)的 supr,就是父類的同名函數(shù) this.supr = supr[proto][k] var undef = {}.fabricatedUndefined var ret = undef try { // this 是當前類,fn 是父類的函數(shù),fn 的上下文是綁定在當前類中,所以就等于父類的方法就繼承到子類中了 ret = fn.apply(this, arguments) } finally { this.supr = tmp } return ret } } // 子類繼承父類的屬性,如果有同名函數(shù),就使用 wrap 方法處理,如果沒有,就完全繼承該屬性 // what : child; o : parent; supr: parentClass function process(what, o, supr) { for (var k in o) { if (o.hasOwnProperty(k)) { what[k] = isFn(o[k]) && isFn(supr[proto][k]) && fnTest.test(o[k]) ? wrap(k, o[k], supr) : o[k] } } } // 實現(xiàn)繼承的主函數(shù), o創(chuàng)建類時的所有函數(shù),fromSub 為1,不明白為什么不把fromSub設置為true/false function extend(o, fromSub) { // must redefine noop each time so it doesn"t inherit from previous arbitrary classes function noop() {} noop[proto] = this[proto] var supr = this , prototype = new noop() , isFunction = isFn(o) , _constructor = isFunction ? o : this , _methods = isFunction ? {} : o function fn() { // 如果當前類設置類 initialize 函數(shù),就把傳給當前類的參數(shù)傳遞給該函數(shù) if (this.initialize) this.initialize.apply(this, arguments) else { // 如果沒有設置 initialize ,傳入類的參數(shù)也能被其它函數(shù)使用 fromSub || isFunction && supr.apply(this, arguments) _constructor.apply(this, arguments) } } // 使用 methods 添加方法到當前類,o 為使用 methods 內(nèi)的方法 fn.methods = function (o) { process(prototype, o, supr) fn[proto] = prototype return this } // 指定 fn 的 constructor fn.methods.call(fn, _methods).prototype.constructor = fn // 使用 ParentClassName.extend 來實現(xiàn)繼承時候的 fn.extend = arguments.callee // 使用 implement 來重寫父類的方法或者拓展父類的方法 // o : 函數(shù)名 ; optFn : 函數(shù) fn[proto].implement = fn.statics = function (o, optFn) { o = typeof o == "string" ? (function () { var obj = {} obj[o] = optFn return obj }()) : o // 使用 process 把 implement 中的函數(shù)添加到當前類中 process(this, o, supr) return this } return fn } return klass });
JS面向對象系列
《javascript高級程序設計》 繼承實現(xiàn)方式
prototype.js 是如何實現(xiàn)JS的類以及類的相關屬性和作用
Mootools.js 是如何實現(xiàn)類,以及類的相關屬性和作用
總結:prototype.js,Mootools.js和klass.js 實現(xiàn)類的方法的異同與優(yōu)劣
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/84513.html
摘要:實現(xiàn)類的步驟第一步是使用新建類,初始化的固定函數(shù)是,不能使用其它名稱子類也是使用新建,父類放在第一個參數(shù)中,如子類中與父類的同名方法,如果需要在父類的同名方法上拓展,在需要在第一個參數(shù)中使用,然后在方法體內(nèi)使用如果需要在類的外面增加方法,可 實現(xiàn)類的步驟 第一步是使用Class.create新建類,初始化的固定函數(shù)是initialize,不能使用其它名稱 子類也是使用Class.cr...
摘要:構建類的方法使用來構建類使用來構建類使用來構建類繼承父類的方法使用子類方法構建子類,繼承父類,在與父類同名的方法中,第一個參數(shù)為,方法體內(nèi)使用來拓展父類的同名方法使用正常構建類后,第一個方法使用來繼承父類,在子類的方法體中,使用來拓展父類的 構建類的方法 Prototype.js使用Class.create來構建類 Mootools.js使用new Class來構建類 klass.j...
摘要:實現(xiàn)類的步驟第一步是使用新建類,初始化的固定函數(shù)是,不能使用其它名稱子類也是使用新建,父類在子類中,使用來繼承,與子類的方法名,同一級別子類中與父類的同名方法,如果需要在父類的同名方法上拓展,需要在子類的同名方法內(nèi),使用如果需要在類的外面增 實現(xiàn)類的步驟 第一步是使用new Class新建類,初始化的固定函數(shù)是initialize,不能使用其它名稱 子類也是使用new Class新建...
摘要:基于函數(shù)進行調(diào)用的,用來確保函數(shù)是在指定的值所在的上下文中調(diào)用的。添加私有函數(shù)目前上面為類庫添加的屬性都是公開的,可以被隨時修改。以基于的富應用開發(fā)為主要學習資料。 控制類庫的作用域 在類和實例中都添加proxy函數(shù),可以在事件處理程序之外處理函數(shù)的時候保持類的作用域。下面是不用proxy的辦法: var Class = function(parent){ var klas...
摘要:實際上,可以將其理解為某種形式的繼承。如果上下文是,則使用全局對象代替。例如的第個參數(shù)是上下文,后續(xù)是實際傳入的參數(shù)序列中允許更換上下文是為了共享狀態(tài),尤其是在事件回調(diào)中。 公開記錄學習JS MVC,不知道能堅持多久= =。以《基于MVC的JavaScript web富應用開發(fā)》為主要學習資料。接上一篇類的學習,發(fā)現(xiàn)實在是看暈了,有些例子是能看懂在干嘛,但是不知道為什么這樣做,有的甚至...
閱讀 9734·2021-11-18 10:02
閱讀 2701·2019-08-30 15:43
閱讀 2717·2019-08-30 13:50
閱讀 1454·2019-08-30 11:20
閱讀 2765·2019-08-29 15:03
閱讀 3693·2019-08-29 12:36
閱讀 979·2019-08-23 17:04
閱讀 670·2019-08-23 14:18