亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

閱讀sea.js源碼小結(jié)

chavesgu / 3516人閱讀

摘要:依賴信息是一個(gè)數(shù)組,比如上面的依賴數(shù)組是源碼如下是利用正則解析依賴的一個(gè)函數(shù)時(shí)間出發(fā)函數(shù)主要看這個(gè)部分注釋是防止拷貝該時(shí)間的回調(diào)函數(shù),防止修改,困惑了一下。對(duì)的賦值需要同步執(zhí)行,不能放在回調(diào)函數(shù)里。

sea.js想解決的問題

惱人的命名沖突

煩瑣的文件依賴

對(duì)應(yīng)帶來(lái)的好處 Sea.js 帶來(lái)的兩大好處:

通過 exports 暴露接口。這意味著不需要命名空間了,更不需要全局變量。這是一種徹底的命名沖突解決方案。

通過 require 引入依賴。這可以讓依賴內(nèi)置,開發(fā)者只需關(guān)心當(dāng)前模塊的依賴,其他事情 Sea.js 都會(huì)自動(dòng)處理好。對(duì)模塊開發(fā)者來(lái)說(shuō),這是一種很好的 關(guān)注度分離,能讓程序員更多地享受編碼的樂趣。

API速查
1. seajs.config
2. seajs.use
3. define
4. require
5. require.async
6. exports
7. module.exports
sea.js的執(zhí)行過程 啟動(dòng)

script標(biāo)簽引入sea.js文件,seajs.config(data)啟動(dòng)配置函數(shù),config函數(shù)會(huì)會(huì)合并所有config配置,seajs.use = function(ids, callback),啟用主腳本

運(yùn)行過程

主腳本啟動(dòng)之后,首先利用request模塊請(qǐng)求主腳本(生成script標(biāo)簽插入head標(biāo)簽中),然后根據(jù)正則解析模塊define的依賴,并對(duì)依賴遞歸解析其依賴。
在運(yùn)行過程中,通過監(jiān)聽發(fā)布者模式,系統(tǒng)內(nèi)置了8個(gè)事件,可用于開發(fā)插件。

resolve       -- 將 id 解析成為 uri 時(shí)觸發(fā)
load          -- 開始加載文件時(shí)觸發(fā)
fetch         -- 具體獲取某個(gè) uri 時(shí)觸發(fā)
request       -- 發(fā)送請(qǐng)求時(shí)觸發(fā)
define         -- 執(zhí)行 define 方法時(shí)觸發(fā)
exec         -- 執(zhí)行 module.factory 時(shí)觸發(fā)
config         -- 調(diào)用 seajs.config 時(shí)觸發(fā)
error          -- 加載腳本文件出現(xiàn) 404 或其他錯(cuò)誤時(shí)觸發(fā)
全局掛載

所有相關(guān)數(shù)據(jù)最后全部掛載在window.seajs下,包括方法及模塊數(shù)據(jù)。

小知識(shí)點(diǎn) exports與module.exports

exports 僅僅是 module.exports 的一個(gè)引用。在 factory 內(nèi)部給 exports 重新賦值時(shí),并不會(huì)改變 module.exports 的值。因此給 exports 賦值是無(wú)效的,不能用來(lái)更改模塊接口。

//源碼如下
// Exec factory
var factory = mod.factory;

var exports = isFunction(factory) ?
  factory.call(mod.exports = {}, require, mod.exports, mod) :
  factory
關(guān)于動(dòng)態(tài)依賴

有時(shí)會(huì)希望可以使用 require 來(lái)進(jìn)行條件加載:

if (todayIsWeekend)
  require("play");
else
  require("work");

但請(qǐng)牢記,從靜態(tài)分析的角度來(lái)看,這個(gè)模塊同時(shí)依賴 play 和 work 兩個(gè)模塊,加載器會(huì)把這兩個(gè)模塊文件都下載下來(lái)。 這種情況下,推薦使用 require.async 來(lái)進(jìn)行條件加載。

//sea.js源碼如下
require.async = function(ids, callback) { //可傳入回調(diào)函數(shù)
  Module.use(ids, callback, uri + "_async_" + cid())  //——async_英語(yǔ)標(biāo)識(shí)這個(gè)腳本是異步加載的,cid用于清除緩存
  return require //返回require方便鏈?zhǔn)秸{(diào)用
}
在開發(fā)時(shí),Sea.js 是如何知道一個(gè)模塊的具體依賴呢?

a.js

define(function(require, exports) {
  var b = require("./b");
  var c = require("./c");
});

Sea.js 在運(yùn)行 define 時(shí),接受 factory 參數(shù),可以通過 factory.toString() 拿到源碼,再通過正則匹配 require 的方式來(lái)得到依賴信息。依賴信息是一個(gè)數(shù)組,比如上面 a.js 的依賴數(shù)組是:["./b", "./c"]

//源碼如下

// Parse dependencies according to the module factory code
if (!isArray(deps) && isFunction(factory)) {  
  deps = typeof parseDependencies === "undefined" ? [] : parseDependencies(factory.toString()) //parseDependencies是利用正則解析依賴的一個(gè)函數(shù)
}
時(shí)間出發(fā)函數(shù)Emit
// Emit event, firing all bound callbacks. Callbacks receive the same
// arguments as `emit` does, apart from the event name
var emit = seajs.emit = function(name, data) {
  var list = events[name]

  if (list) {
    // Copy callback lists to prevent modification
    list = list.slice()

    // Execute event callbacks, use index because it"s the faster.
    for(var i = 0, len = list.length; i < len; i++) {
      list[i](data)
    }
  }

  return seajs
}

主要看這個(gè)部分list = list.slice(),注釋是防止拷貝該時(shí)間的回調(diào)函數(shù),防止修改,困惑了一下。

原因是Javascript中賦值時(shí),對(duì)于引用數(shù)據(jù)類型,都是傳地址。
所以這里,如果想防止觸發(fā)事件的過程中回調(diào)函數(shù)被更改,必須對(duì)這個(gè)list數(shù)組進(jìn)行拷貝,而并非只是將list指向events[name]的地址。

根據(jù)debug值配置是否刪除動(dòng)態(tài)插入的腳本
// Remove the script to reduce memory leak
      if (!data.debug) {
        head.removeChild(node)
      }

這里思考了蠻久,為什么可以刪除動(dòng)態(tài)插入的腳本?這樣腳本還會(huì)生效嗎?

首先,必須了解計(jì)算機(jī)內(nèi)存分為

靜態(tài)數(shù)據(jù)區(qū) (用來(lái)存放程序中初始化的全局變量的一塊內(nèi)存區(qū)域)

代碼區(qū) (通常用來(lái)存放執(zhí)行代碼的一塊內(nèi)存區(qū)域)

棧區(qū) (棧在進(jìn)程運(yùn)行時(shí)產(chǎn)生,一個(gè)進(jìn)程有一個(gè)進(jìn)程棧。棧用來(lái)存儲(chǔ)程序臨時(shí)存放的局部變量,即函數(shù)內(nèi)定義的變量 不包括static 類型的。函數(shù)被調(diào)用時(shí),他的形參也會(huì)被壓棧。

堆區(qū) (用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并且不固定,可動(dòng)態(tài)擴(kuò)展。當(dāng)進(jìn)程調(diào)用malloc等分配內(nèi)存時(shí),新分配的內(nèi)存被動(dòng)態(tài)的添加到堆上(堆被擴(kuò)大),當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的‘ 內(nèi)存從堆中剔除)

這些在Javascript中都被屏蔽了,大部分時(shí)候我們都不需要考慮,但是如果要深入了解的話,則是必須要知道的知識(shí)。

首先HTML文檔中的JS腳本在計(jì)算機(jī)中作為指令被讀入內(nèi)存,之后開始執(zhí)行,CPU開始一條一條指令讀取,比如,讀取到var cool = "wilson"時(shí),就會(huì)在內(nèi)存中分配一個(gè)6字符大小的內(nèi)存,一個(gè)function也一樣會(huì)在內(nèi)存中占據(jù)一定大小。所以,當(dāng)指令全部運(yùn)行完之后,指令本身其實(shí)已經(jīng)沒有用了,但是仍然給占據(jù)了一部分內(nèi)存。
當(dāng)你點(diǎn)擊按鈕觸發(fā)一個(gè)回調(diào)函數(shù)時(shí),并非去讀取指令,而是讀取內(nèi)存中這個(gè)回調(diào)函數(shù)的地址。所以刪除這些動(dòng)態(tài)加載的JS文件是沒有問題的。

ID 和路徑匹配原則

所謂 ID 和路徑匹配原則 是指,使用 seajs.use 或 require 進(jìn)行引用的文件,如果是具名模塊(即定義了 ID 的模塊),會(huì)把 ID 和 seajs.use 的路徑名進(jìn)行匹配,如果一致,則正確執(zhí)行模塊返回結(jié)果。反之,則返回 null。

對(duì) module.exports 的賦值需要同步執(zhí)行,不能放在回調(diào)函數(shù)里。下面這樣是不行的
// x.js
define(function(require, exports, module) {

  // 錯(cuò)誤用法
  setTimeout(function() {
    module.exports = { a: "hello" };
  }, 0);

});

//在 y.js 里有調(diào)用到上面的 x.js:

// y.js
define(function(require, exports, module) {

  var x = require("./x");

  // 無(wú)法立刻得到模塊 x 的屬性 a
  console.log(x.a); // undefined

});

WilsonLiu"s blog首發(fā)地址:http://blog.wilsonliu.cn

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79775.html

相關(guān)文章

  • 前端模塊化詳解(完整版)

    摘要:二模塊化規(guī)范概述應(yīng)用由模塊組成,采用模塊規(guī)范。模塊化語(yǔ)法命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。 前言 在JavaScript發(fā)展初期就是為了實(shí)現(xiàn)簡(jiǎn)單的頁(yè)面交互邏輯,寥寥數(shù)語(yǔ)即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁(yè)面邏輯遷移到了客戶端(表單驗(yàn)證等),隨著web2.0時(shí)代的到來(lái),Ajax技術(shù)得到廣泛應(yīng)用,jQuery等前端庫(kù)層出不窮,前端代碼日益膨脹,此時(shí)...

    Sanchi 評(píng)論0 收藏0
  • 前端模塊化詳解(完整版)

    摘要:二模塊化規(guī)范概述應(yīng)用由模塊組成,采用模塊規(guī)范。模塊化語(yǔ)法命令用于規(guī)定模塊的對(duì)外接口,命令用于輸入其他模塊提供的功能。 前言 在JavaScript發(fā)展初期就是為了實(shí)現(xiàn)簡(jiǎn)單的頁(yè)面交互邏輯,寥寥數(shù)語(yǔ)即可;如今CPU、瀏覽器性能得到了極大的提升,很多頁(yè)面邏輯遷移到了客戶端(表單驗(yàn)證等),隨著web2.0時(shí)代的到來(lái),Ajax技術(shù)得到廣泛應(yīng)用,jQuery等前端庫(kù)層出不窮,前端代碼日益膨脹,此時(shí)...

    Pines_Cheng 評(píng)論0 收藏0
  • sea.js

    摘要:目標(biāo)了解目前公司所用得代碼模塊式開發(fā)。比較目前比較流行得框架。模塊化可以讓每個(gè)文件的職責(zé)單一,非常有利于代碼的維護(hù)。模塊定義規(guī)范與的模塊規(guī)范非常相近。一類是以國(guó)內(nèi)的等類庫(kù)為代表的大教堂模式。 目標(biāo):1.了解目前公司所用得sea.js,代碼模塊式開發(fā)。 2.比較目前比較流行得bootstrap,angularJS,reactJS框架。 參考:http://seajs.org/docs/...

    renweihub 評(píng)論0 收藏0
  • 前端20個(gè)靈魂拷問 徹底搞明白你就是中級(jí)前端工程師 【中篇】

    摘要:前端個(gè)靈魂拷問,徹底搞明白你就是中級(jí)前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會(huì)多一些。所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。此規(guī)范其實(shí)是在推廣過程中產(chǎn)生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個(gè)靈魂拷問,徹底搞明白你就是中級(jí)前端工程師...

    MartinDai 評(píng)論0 收藏0
  • 前端20個(gè)靈魂拷問 徹底搞明白你就是中級(jí)前端工程師 【中篇】

    摘要:前端個(gè)靈魂拷問,徹底搞明白你就是中級(jí)前端工程師上篇感覺大家比較喜歡看這種類型的文章,以后會(huì)多一些。所有依賴這個(gè)模塊的語(yǔ)句,都定義在一個(gè)回調(diào)函數(shù)中,等到加載完成之后,這個(gè)回調(diào)函數(shù)才會(huì)運(yùn)行。此規(guī)范其實(shí)是在推廣過程中產(chǎn)生的。 showImg(https://segmentfault.com/img/bVbwAMU?w=700&h=394); 前端20個(gè)靈魂拷問,徹底搞明白你就是中級(jí)前端工程師...

    coolpail 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<