真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

javascript模塊化,js模塊化開發(fā)

javascript模塊化是什么及其優(yōu)缺點(diǎn)介紹

如今backbone、emberjs、spinejs、batmanjs

10年積累的成都做網(wǎng)站、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先做網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有東湖免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

等MVC框架侵襲而來。CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs等模塊化的JavaScript撲面而

來。web前端已經(jīng)演變成大前端,web前端的發(fā)展速度之快。

1)我們來看看什么是模塊化?

模塊化是一種將系統(tǒng)分離成獨(dú)立功能部分的方法,可將系統(tǒng)分割成獨(dú)立的功能部分,嚴(yán)格定義模塊接口、模塊間具有透明性。javascript中的模塊在一些C、PHP、java中比較常見:

c中使用include 包含.h文件;php中使用require_once包含.php文件

java使用import導(dǎo)入包

此中都有模塊化的思想。

2)模塊化的優(yōu)缺點(diǎn):

a優(yōu)點(diǎn):

可維護(hù)性

1.靈活架構(gòu),焦點(diǎn)分離

2.方便模塊間組合、分解

3.方便單個(gè)模塊功能調(diào)試、升級(jí)

4.多人協(xié)作互不干擾

可測(cè)試性

1.可分單元測(cè)試

b缺點(diǎn):

性能損耗

1.系統(tǒng)分層,調(diào)用鏈會(huì)很長

2.模塊間通信,模塊間發(fā)送消息會(huì)很耗性能

3)最近的項(xiàng)目中也有用到模塊化,

使用的是seajs,但是當(dāng)引用到j(luò)query,jquery easyui/或者jquery

UI組件時(shí),有可能會(huì)用到很多jquery插件,那這樣要是實(shí)現(xiàn)一個(gè)很復(fù)雜的交互時(shí),模塊間的依賴會(huì)很多,使用define()方法引入模塊會(huì)很多,不知

有么有什么好的方法?

4)附:

內(nèi)聚度

內(nèi)聚度指模塊內(nèi)部實(shí)現(xiàn),它是信息隱藏和局部化概念的自然擴(kuò)展,它標(biāo)志著一個(gè)模塊內(nèi)部各成分彼此結(jié)合的緊密程度。好處也很明顯,當(dāng)把相關(guān)的任務(wù)分組后去閱讀就容易多了。 設(shè)計(jì)時(shí)應(yīng)該盡可能的提高模塊內(nèi)聚度,從而獲得較高的模塊獨(dú)立性。

耦合度

耦合度則是指模塊之間的關(guān)聯(lián)程度的度量。耦合度取決于模塊之間接口的復(fù)雜性,進(jìn)入或調(diào)用模塊的位置等。與內(nèi)聚度相反,在設(shè)計(jì)時(shí)應(yīng)盡量追求松散耦合的系統(tǒng)。

怎么快速上手JavaScript中的ES6,ES6中的解構(gòu),運(yùn)算符,類,繼承模塊化 有什么簡單的理解?

模塊化在項(xiàng)目中十分的重要,一個(gè)復(fù)雜的項(xiàng)目肯定有很多相似的功能模塊,如果每次都需要重新編寫模塊肯定既費(fèi)時(shí)又耗力。但是引用別人編寫模塊的前提是要有統(tǒng)一的“打開姿勢(shì)”,如果每個(gè)人有各自的寫法,那么肯定會(huì)亂套,下面介紹幾種JS的模塊化的規(guī)范。

一:模塊化進(jìn)程一:script標(biāo)簽

這是最原始的 JavaScript 文件加載方式,如果把每一個(gè)文件看做是一個(gè)模塊,那么他們的接口通常是暴露在全局作用域下,也就是定義在 window 對(duì)象中,不同模塊的接口調(diào)用都是一個(gè)作用域中,一些復(fù)雜的框架,會(huì)使用命名空間的概念來組織這些模塊的接口。

缺點(diǎn):

1、污染全局作用域

2、開發(fā)人員必須主觀解決模塊和代碼庫的依賴關(guān)系

3、文件只能按照script標(biāo)簽的書寫順序進(jìn)行加載

4、在大型項(xiàng)目中各種資源難以管理,長期積累的問題導(dǎo)致代碼庫混亂不堪

二:模塊化進(jìn)程二:CommonJS規(guī)范

該規(guī)范的核心思想是允許模塊通過require方法來同步加載所要依賴的其他模塊,然后通過 exports 或 module.exports 來導(dǎo)出需要暴露的接口。

require("module");

require("../file.js");

exports.doStuff = function(){};

module.exports = someValue;

優(yōu)點(diǎn):

1、簡單并容易使用

2、服務(wù)器端模塊便于重用

缺點(diǎn):

1、同步的模塊加載方式不適合在瀏覽器環(huán)境中,同步意味著阻塞加載,瀏覽器資源是異步加載的

2、不能非阻塞的并行加載多個(gè)模塊

module.exports與exports的區(qū)別

1、exports 是指向的 module.exports 的引用

2、module.exports 初始值為一個(gè)空對(duì)象 {},所以 exports 初始值也是 {}

3、require() 返回的是 module.exports 而不是 exports

exports示例:

// app.js

var circle = require('./circle');

console.log(circle.area(4));

// circle.js

exports.area = function(r){

return r * r * Math.PI;

}

module.exports示例:

// app.js

var area = require('./area');

console.log(area(4));

// area.js

module.exports = function(r){

return r * r * Math.PI;

}

錯(cuò)誤的情況:

// app.js

var area = require('./area');

console.log(area(4));

// area.js

exports = function(r){

return r * r * Math.PI;

}

其實(shí)是對(duì) exports 進(jìn)行了覆蓋,也就是說 exports 指向了一塊新的內(nèi)存(內(nèi)容為一個(gè)計(jì)算圓面積的函數(shù)),也就是說 exports 和 module.exports 不再指向同一塊內(nèi)存,也就是說此時(shí) exports 和 module.exports 毫無聯(lián)系,也就是說 module.exports 指向的那塊內(nèi)存并沒有做任何改變,仍然為一個(gè)空對(duì)象{},也就是說area.js導(dǎo)出了一個(gè)空對(duì)象,所以我們?cè)?app.js 中調(diào)用 area(4) 會(huì)報(bào) TypeError: object is not a function 的錯(cuò)誤。

總結(jié):當(dāng)我們想讓模塊導(dǎo)出的是一個(gè)對(duì)象時(shí), exports 和 module.exports 均可使用(但 exports 也不能重新覆蓋為一個(gè)新的對(duì)象),而當(dāng)我們想導(dǎo)出非對(duì)象接口時(shí),就必須也只能覆蓋 module.exports 。

三:模塊化進(jìn)程三:AMD規(guī)范

由于瀏覽器端的模塊不能采用同步的方式加載,會(huì)影響后續(xù)模塊的加載執(zhí)行,因此AMD(Asynchronous Module Definition異步模塊定義)規(guī)范誕生了。

AMD標(biāo)準(zhǔn)中定義了以下兩個(gè)API

1、require([module], callback);

2、define(id, [depends], callback);

require接口用來加載一系列模塊,define接口用來定義并暴露一個(gè)模塊。

示例:

define("module", ["dep1", "dep2"], function(d1, d2){

return someExportedValue;

});

require(["module", "../file"], function(module, file){ /* ... */ });

優(yōu)點(diǎn):

1、適合在瀏覽器環(huán)境中異步加載模塊

2、可以并行加載多個(gè)模塊

缺點(diǎn):

1、提高了開發(fā)成本,代碼的閱讀和書寫比較困難,模塊定義方式的語義不順暢

2、不符合通用的模塊化思維方式,是一種妥協(xié)的實(shí)現(xiàn)

四:模塊化進(jìn)程四:CMD規(guī)范

CMD(Common Module Definition)規(guī)范和AMD很相似,盡量保持簡單,并與CommonJS和Node.js的 Modules 規(guī)范保持了很大的兼容性。在CMD規(guī)范中,一個(gè)模塊就是一個(gè)文件。

示例:

define(function(require, exports, module){

var $ = require('jquery');

var Spinning = require('./spinning');

exports.doSomething = ...

module.exports = ...

})

優(yōu)點(diǎn):

1、依賴就近,延遲執(zhí)行

2、可以很容易在 Node.js 中運(yùn)行

缺點(diǎn):

1、依賴 SPM 打包,模塊的加載邏輯偏重

AMD和CMD的區(qū)別

AMD和CMD起來很相似,但是還是有一些細(xì)微的差別,讓我們來看一下他們的區(qū)別在哪里:

1、對(duì)于依賴的模塊,AMD是提前執(zhí)行,CMD是延遲執(zhí)行。

2、AMD推崇依賴前置;CMD推崇依賴就近,只有在用到某個(gè)模塊的時(shí)候再去require。看代碼:

// AMD

define(['./a', './b'], function(a, b){ // 依賴必須一開始就寫好

a.doSomething()

// 此處略去 100 行

b.doSomething()

...

});

// CMD

define(function(require, exports, module){

var a = require('./a')

a.doSomething()

// 此處略去 100 行

var b = require('./b')

// 依賴可以就近書寫

b.doSomething()

// ...

});

3、AMD 的 API 默認(rèn)是一個(gè)當(dāng)多個(gè)用,CMD 的 API 嚴(yán)格區(qū)分,推崇職責(zé)單一。

五:模塊化進(jìn)程五:ES6模塊化

EcmaScript6標(biāo)準(zhǔn)增加了JavaScript語言層面的模塊體系定義。ES6 模塊的設(shè)計(jì)思想,是盡量的靜態(tài)化,使得編譯時(shí)就能確定模塊的依賴關(guān)系,以及輸入和輸出的變量。CommonJS和AMD模塊,都只能在運(yùn)行時(shí)確定這些東西。

在 ES6 中,我們使用export關(guān)鍵字來導(dǎo)出模塊,使用import關(guān)鍵字引用模塊。需要說明的是,ES6的這套標(biāo)準(zhǔn)和目前的標(biāo)準(zhǔn)沒有直接關(guān)系,目前也很少有JS引擎能直接支持。因此Babel的做法實(shí)際上是將不被支持的import翻譯成目前已被支持的require。

盡管目前使用import和require的區(qū)別不大(本質(zhì)上是一回事),但依然強(qiáng)烈推薦使用import關(guān)鍵字,因?yàn)橐坏㎎S引擎能夠解析ES6的import關(guān)鍵字,整個(gè)實(shí)現(xiàn)方式就會(huì)和目前發(fā)生比較大的變化。如果目前就開始使用import關(guān)鍵字,將來代碼的改動(dòng)會(huì)非常小。

示例:

import "jquery";

export functiondoStuff(){}

module "localModule" {}

優(yōu)點(diǎn):

1、容易進(jìn)行靜態(tài)分析

2、面向未來的 EcmaScript 標(biāo)準(zhǔn)

缺點(diǎn):

1、原生瀏覽器端還沒有實(shí)現(xiàn)該標(biāo)準(zhǔn)

2、全新的命令字,新版的 Node.js才支持

原生javascript 模塊化怎樣傳遞參數(shù)

:可以通過高度抽象出很多東西的相同點(diǎn),進(jìn)行寫一個(gè)模塊,簡化代碼結(jié)構(gòu)

javascript模塊化是什么?優(yōu)缺點(diǎn)有哪些?

可維護(hù)性

靈活架構(gòu),焦點(diǎn)分離

方便模塊間組合、分解

方便單個(gè)模塊功能調(diào)試、升級(jí)

多人協(xié)作互不干擾

可測(cè)試性,可分單元測(cè)試;

性能損耗

系統(tǒng)分層,調(diào)用鏈會(huì)很長

模塊間通信,模塊間發(fā)送消息會(huì)很耗性能

最近的項(xiàng)目中也有用到模塊化;

使用的是seajs,但是當(dāng)引用到j(luò)query,jquery easyui/或者jquery;

UI組件時(shí),有可能會(huì)用到很多jquery插件,那這樣要是實(shí)現(xiàn)一個(gè)很復(fù)雜的交互時(shí),模塊間的依賴會(huì)很多,使用define()方法引入模塊會(huì)很多。

js的模塊化編程有哪些方式

基礎(chǔ)

我們首先簡單地概述一下,自從三年前Eric Miraglia(YUI的開發(fā)者)第一次發(fā)表博客描述模塊化模式以來的一些模塊化模式。如果你已經(jīng)對(duì)于這些模塊化模式非常熟悉了,大可以直接跳過本節(jié),從“進(jìn)階模式”開始閱讀。

匿名閉包

這是一種讓一切變?yōu)榭赡艿幕窘Y(jié)構(gòu),同時(shí)它也是Javascript最棒的特性。我們將簡單地創(chuàng)建一個(gè)匿名函數(shù)并立即執(zhí)行它。所有的代碼將跑在這個(gè)函數(shù)內(nèi),生存在一個(gè)提供私有化的閉包中,它足以使得這些閉包中的變量能夠貫穿我們的應(yīng)用的整個(gè)生命周期。

復(fù)制代碼 代碼如下:

(function () {

// ... all vars and functions are in this scope only

// still maintains access to all globals

}());

注意這對(duì)包裹匿名函數(shù)的最外層括號(hào)。因?yàn)镴avascript的語言特性,這對(duì)括號(hào)是必須的。在js中由關(guān)鍵詞function開頭的語句總是會(huì)被認(rèn)為是函數(shù)聲明式。把這段代碼包裹在括號(hào)中就可以讓解釋器知道這是個(gè)函數(shù)表達(dá)式。

全局變量導(dǎo)入

Javascript有一個(gè)特性叫做隱式全局變量。無論一個(gè)變量名在哪兒被用到了,解釋器會(huì)根據(jù)作用域鏈來反向找到這個(gè)變量的var聲明語句。如果沒有找到var聲明語句,那么這個(gè)變量就會(huì)被視為全局變量。如果這個(gè)變量用在一句賦值語句中,同時(shí)這個(gè)變量又不存在時(shí),就會(huì)創(chuàng)建出一個(gè)全局變量。這意味著在匿名閉包中使用或創(chuàng)建全局變量是很容易的。不幸的是,這會(huì)導(dǎo)致寫出的代碼極難維護(hù),因?yàn)閷?duì)于人的直觀感受來說,一眼根本分不清那些是全局的變量。

幸運(yùn)的是,我們的匿名函數(shù)提供了簡單的變通方法。只要將全局變量作為參數(shù)傳遞到我們的匿名函數(shù)中,就可以得到比隱式全局變量更清晰又快速的代碼了。下面是示例:

復(fù)制代碼 代碼如下:

(function ($, YAHOO) {

// now have access to globals jQuery (as $) and YAHOO in this code

}(jQuery, YAHOO));

模塊導(dǎo)出

有時(shí)你不僅想要使用全局變量,你還想要聲明它們,以供反復(fù)使用。我們可以很容易地通過導(dǎo)出它們來做到這一點(diǎn)——通過匿名函數(shù)的返回值。這樣做將會(huì)完成一個(gè)基本的模塊化模式雛形,接下來會(huì)是一個(gè)完整的例子:

復(fù)制代碼 代碼如下:

var MODULE = (function () {

var my = {},

privateVariable = 1;

function privateMethod() {

// ...

}

my.moduleProperty = 1;

my.moduleMethod = function () {

// ...

};

return my;

}());

注意我們已經(jīng)聲明了一個(gè)叫做MODULE的全局模塊,它擁有2個(gè)公有的屬性:一個(gè)叫做MODULE.moduleMethod的方法和一個(gè)叫做MODULE.moduleProperty的變量。另外,它還維護(hù)了一個(gè)利用匿名函數(shù)閉包的、私有的內(nèi)置狀態(tài)。同時(shí),我們可以很容易地導(dǎo)入需要的全局變量,并像之前我們所學(xué)到的那樣來使用這個(gè)模塊化模式。

進(jìn)階模式

上面一節(jié)所描述的基礎(chǔ)已經(jīng)足以應(yīng)對(duì)許多情況,現(xiàn)在我們可以將這個(gè)模塊化模式進(jìn)一步的發(fā)展,創(chuàng)建更多強(qiáng)大的、可擴(kuò)展的結(jié)構(gòu)。讓我們從MODULE模塊開始,一一介紹這些進(jìn)階模式。

放大模式

整個(gè)模塊必須在一個(gè)文件中是模塊化模式的一個(gè)限制。任何一個(gè)參與大型項(xiàng)目的人都會(huì)明白將js拆分多個(gè)文件的價(jià)值。幸運(yùn)的是,我們擁有一個(gè)很棒的實(shí)現(xiàn)來放大模塊。首先,我們導(dǎo)入一個(gè)模塊,并為它添加屬性,最后再導(dǎo)出它。下面是一個(gè)例子——從原本的MODULE中放大它:

復(fù)制代碼 代碼如下:

var MODULE = (function (my) {

my.anotherMethod = function () {

// added method...

};

return my;

}(MODULE));

我們用var關(guān)鍵詞來保證一致性,雖然它在此處不是必須的。在這段代碼執(zhí)行完之后,我們的模塊就已經(jīng)擁有了一個(gè)新的、叫做MODULE.anotherMethod的公有方法。這個(gè)放大文件也會(huì)維護(hù)它自己的私有內(nèi)置狀態(tài)和導(dǎo)入的對(duì)象。

寬放大模式

我們的上面例子需要我們的初始化模塊最先被執(zhí)行,然后放大模塊才能執(zhí)行,當(dāng)然有時(shí)這可能也不一定是必需的。Javascript應(yīng)用可以做到的、用來提升性能的、最棒的事之一就是異步執(zhí)行腳本。我們可以創(chuàng)建靈活的多部分模塊并通過寬放大模式使它們可以以任意順序加載。每一個(gè)文件都需要按下面的結(jié)構(gòu)組織:

復(fù)制代碼 代碼如下:

var MODULE = (function (my) {

// add capabilities...

return my;

}(MODULE || {}));

在這個(gè)模式中,var表達(dá)式使必需的。注意如果MODULE還未初始化過,這句導(dǎo)入語句會(huì)創(chuàng)建MODULE。這意味著你可以用一個(gè)像LABjs的工具來并行加載你所有的模塊文件,而不會(huì)被阻塞。

緊放大模式

寬放大模式非常不錯(cuò),但它也會(huì)給你的模塊帶來一些限制。最重要的是,你不能安全地覆蓋模塊的屬性。你也無法在初始化的時(shí)候,使用其他文件中的屬性(但你可以在運(yùn)行的時(shí)候用)。緊放大模式包含了一個(gè)加載的順序序列,并且允許覆蓋屬性。這兒是一個(gè)簡單的例子(放大我們的原始MODULE):

復(fù)制代碼 代碼如下:

var MODULE = (function (my) {

var old_moduleMethod = my.moduleMethod;

my.moduleMethod = function () {

// method override, has access to old through old_moduleMethod...

};

return my;

}(MODULE));

我們?cè)谏厦娴睦又懈采w了MODULE.moduleMethod的實(shí)現(xiàn),但在需要的時(shí)候,可以維護(hù)一個(gè)對(duì)原來方法的引用。

克隆與繼承

復(fù)制代碼 代碼如下:

var MODULE_TWO = (function (old) {

var my = {},

key;

for (key in old) {

if (old.hasOwnProperty(key)) {

my[key] = old[key];

}

}

var super_moduleMethod = old.moduleMethod;

my.moduleMethod = function () {

// override method on the clone, access to super through super_moduleMethod

};

return my;

}(MODULE));

這個(gè)模式可能是最缺乏靈活性的一種選擇了。它確實(shí)使得代碼顯得很整潔,但那是用靈活性的代價(jià)換來的。正如我上面寫的這段代碼,如果某個(gè)屬性是對(duì)象或者函數(shù),它將不會(huì)被復(fù)制,而是會(huì)成為這個(gè)對(duì)象或函數(shù)的第二個(gè)引用。修改了其中的某一個(gè)就會(huì)同時(shí)修改另一個(gè)(譯者注:因?yàn)樗鼈兏揪褪且粋€(gè)?。。_@可以通過遞歸克隆過程來解決這個(gè)對(duì)象克隆問題,但函數(shù)克隆可能無法解決,也許用eval可以解決吧。因此,我在這篇文章中講述這個(gè)方法僅僅是考慮到文章的完整性。

跨文件私有變量

把一個(gè)模塊分到多個(gè)文件中有一個(gè)重大的限制:每一個(gè)文件都維護(hù)了各自的私有變量,并且無法訪問到其他文件的私有變量。但這個(gè)問題是可以解決的。這里有一個(gè)維護(hù)跨文件私有變量的、寬放大模塊的例子:

復(fù)制代碼 代碼如下:

var MODULE = (function (my) {

var _private = my._private = my._private || {},

_seal = my._seal = my._seal || function () {

delete my._private;

delete my._seal;

delete my._unseal;

},

_unseal = my._unseal = my._unseal || function () {

my._private = _private;

my._seal = _seal;

my._unseal = _unseal;

};

// permanent access to _private, _seal, and _unseal

return my;

}(MODULE || {}));

所有文件可以在它們各自的_private變量上設(shè)置屬性,并且它理解可以被其他文件訪問。一旦這個(gè)模塊加載完成,應(yīng)用程序可以調(diào)用MODULE._seal()來防止外部對(duì)內(nèi)部_private的調(diào)用。如果這個(gè)模塊需要被重新放大,在任何一個(gè)文件中的內(nèi)部方法可以在加載新的文件前調(diào)用_unseal(),并在新文件執(zhí)行好以后再次調(diào)用_seal()。我如今在工作中使用這種模式,而且我在其他地方還沒有見過這種方法。我覺得這是一種非常有用的模式,很值得就這個(gè)模式本身寫一篇文章。

子模塊

我們的最后一種進(jìn)階模式是顯而易見最簡單的。創(chuàng)建子模塊有許多優(yōu)秀的實(shí)例。這就像是創(chuàng)建一般的模塊一樣:

復(fù)制代碼 代碼如下:

MODULE.sub = (function () {

var my = {};

// ...

return my;

}());

雖然這看上去很簡單,但我覺得還是值得在這里提一提。子模塊擁有一切一般模塊的進(jìn)階優(yōu)勢(shì),包括了放大模式和私有化狀態(tài)。


文章標(biāo)題:javascript模塊化,js模塊化開發(fā)
分享鏈接:http://weahome.cn/article/dseeeso.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部