#JSPatch詳解(JavaScript 模塊 基礎篇)---defineClass,require

JSPatch詳解(JavaScript 模塊 基礎篇)

不是專業的JS人員,半吊子,主要寫給IOSer來看的。

匿名函數

打開JSPatch.js,先把所有的方法給不展開,就是鎖在一起,就看到一個不知道是什么鬼的東西,如下

(function(){...})() 

好吧!這個東西叫做匿名函數“function(){...}”。一般js庫都采用這種自執行的匿名函數來保護內部變量

很明顯作者是害怕我們破壞了他的內部構造嘛~~

這東西其實跟我們所說的私有函數私有變量差不多

暴露方法

之前講到作者用一個自動執行的匿名函數來保護他的內部變量和函數。那么我們外面就沒法訪問里面的那些方法了。這個坑爹的問題咋辦呢?

var global = this
(function() {
    ....
    global.defineClass = function(....) {
    }
    ....
})()

用上面這種形式把defineClass等一系列需要公布的function,公布出來了

作者很機智的區分了共有方法和私有方法,那就是帶_的都是私有的,不帶的都是共有的。

defineClass

這個方法基本是接觸JSPatch的起步吧,一般我們這么玩

var methodName = “name”
var method = {
   handleBtn: function(sender) {
    //balabala
    }
}
var props = ["data":"test"]
var classMethod = {
    test:function () {
        //balabala
    }
}
defineClass(methodName,props,method,classMethod)

也可以這么玩

defineClass(methodName,method,classMethod)

還可以這么玩

defineClass(methodName,method)

愛咋玩就咋玩,關我屁事~
就一個規則,methodName是String,props 必須是個Array,method和classMethod是個對象
那就來看看作者的defineClass的定義

global.defineClass = function(declaration, properties, instMethods, clsMethods) {...}

defineClass就是可以傳三個參數

然后他為什么支持我們的瞎折騰呢

if (!(properties instanceof Array)) {
  clsMethods = instMethods
  instMethods = properties
  properties = null
}

在里面判斷了呀。。。如果properties不是一個array的話,他就當做是個method了

在下面的東西各位看官可以先不關注了。

Require

在這之后就是Require,也可以作死的寫成各種各樣的

var strRequire = "UIView,UILabel"
var strRequire_die = "UIButton"

require(strRequire,strRequire_die)

那么再來看看作者這個Require是怎么玩的吧

global.require = function() {
var lastRequire
for (var i = 0; i < arguments.length; i ++) {
  arguments[i].split(',').forEach(function(clsName) {
    lastRequire = _require(clsName.trim())
  })
}
return lastRequire

}

OK!他是檢測了所有的參數,然后把所有的參數中用“,”分開,分別調用了這個_require方法

那么他的_require方法是干什么用的呢

 var _require = function(clsName) {
if (!global[clsName]) {
  global[clsName] = {
    __clsName: clsName
  }
} 
return global[clsName]

}

很多小伙伴看到可能有點小懵逼,這也是我為什么在defineClass那邊讓大家先停一下的原因。

以上三段代碼跑完之后的global就變成這個樣子了

global = {
 ...
    "UILabel" :{
        __clsName:"UILabel"
    },
    "UIView":{
        __clsName : "UIView"
     },
    "UIButton":{
        __clsName : "UIButton"
     }
 ...
}

是滴,他把這些Class都加到了Global的屬性里面了。
跑完這些你會拿到一個對象,這個對象是這樣的

{
    __clsName:"UIButton"
}

這個時候的疑問就在于怎么使用,或者說怎么就能使用了?

require("UIButton").alloc().init()
//or
require("UIButton")
var button = UIButton.alloc().init()

global里面有了這個UIButton能直接調用UIButton這一點大家都能想明白,可是為什么就有alloc()了?各位看官不要急
這里就是需要從OC入手了

static NSString *_regexStr = @"(?<!\\\\)\\.\\s*(\\w+)\\s*\\(";
static NSString *_replaceStr = @".__c(\"$1\")(";

+ (JSValue *)_evaluateScript:(NSString *)script     withSourceURL:(NSURL *)resourceURL
{
...
NSString *formatedScript = [NSString stringWithFormat:
@";(function(){try{\n%@\n}catch(e){_OC_catch(e.message, e.stack)}})();",
 [_regex stringByReplacingMatchesInString:script options:0 range:
 NSMakeRange(0, script.length) withTemplate:_replaceStr]];
...
    }

看上面一串東西可能你覺得煩,那么我告訴你把,他的作用就是

UIView.alloc().init()
//->
UIView.__c("alloc")().__c("init")()

這時候你就要問了,那么這個__c()函數咋來的,看官別急,我們在看會js

  for (var method in _customMethods) {
if (_customMethods.hasOwnProperty(method)) {
  Object.defineProperty(Object.prototype, method, {value: _customMethods[method], configurable:false, enumerable: false})
 }
  }

這里給每個object對象都加上了_customMethods里面的所有方法,那么這個methods里面是什么鬼呢,我就不告訴你,賣個小關子,因為可能大家忽略了一個東西,UIView.__c("alloc")()這后面還有個"()",所以呢我們這個函數返回的肯定得是個function,好了,不逗你們玩了看正題,

//我這里都用了縮寫,為了大家能集中精力先關心重點
//是不是很想打我,你又打不到我
var _customMethods = {
    __c:func(methodName){
        ...
        return function(...){
            ...
        }
    }
    ...
}

那么目前為止require的這一套邏輯在js里面是的可以跑起來了,按標題的來,先不去關心oc里面是玩的什么鬼。
有些可能會問,require沒有調用這個_customMethods啊,為啥,提示你一下看下第一條,這是一個自動執行的匿名函數。
感謝 “大師”的JS支持

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容