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

JSPatch詳解(JavaScript 模塊 基礎(chǔ)篇)

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

匿名函數(shù)

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

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

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

很明顯作者是害怕我們破壞了他的內(nèi)部構(gòu)造嘛~~

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

暴露方法

之前講到作者用一個(gè)自動(dòng)執(zhí)行的匿名函數(shù)來保護(hù)他的內(nèi)部變量和函數(shù)。那么我們外面就沒法訪問里面的那些方法了。這個(gè)坑爹的問題咋辦呢?

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

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

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

defineClass

這個(gè)方法基本是接觸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)

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

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

defineClass就是可以傳三個(gè)參數(shù)

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

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

在里面判斷了呀。。。如果properties不是一個(gè)array的話,他就當(dāng)做是個(gè)method了

在下面的東西各位看官可以先不關(guān)注了。

Require

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

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

require(strRequire,strRequire_die)

那么再來看看作者這個(gè)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!他是檢測了所有的參數(shù),然后把所有的參數(shù)中用“,”分開,分別調(diào)用了這個(gè)_require方法

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

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

}

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

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

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

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

{
    __clsName:"UIButton"
}

這個(gè)時(shí)候的疑問就在于怎么使用,或者說怎么就能使用了?

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

global里面有了這個(gè)UIButton能直接調(diào)用UIButton這一點(diǎn)大家都能想明白,可是為什么就有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")()

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

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

這里給每個(gè)object對象都加上了_customMethods里面的所有方法,那么這個(gè)methods里面是什么鬼呢,我就不告訴你,賣個(gè)小關(guān)子,因?yàn)榭赡艽蠹液雎粤艘粋€(gè)東西,UIView.__c("alloc")()這后面還有個(gè)"()",所以呢我們這個(gè)函數(shù)返回的肯定得是個(gè)function,好了,不逗你們玩了看正題,

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

那么目前為止require的這一套邏輯在js里面是的可以跑起來了,按標(biāo)題的來,先不去關(guān)心oc里面是玩的什么鬼。
有些可能會(huì)問,require沒有調(diào)用這個(gè)_customMethods啊,為啥,提示你一下看下第一條,這是一個(gè)自動(dòng)執(zhí)行的匿名函數(shù)。
感謝 “大師”的JS支持

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容