欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript單一職責原則深入分析

 更新時間:2022年08月09日 14:30:05   作者:夏安  
這篇文章主要介紹了理解JavaScript單一職責原則,單一職責原則(SRP:Single?responsibility?principle)又稱單一功能原則,面向?qū)ο笪鍌€基本原則(SOLID)之一,下文更多相關(guān)介紹感興趣的小伙伴可以參考一下

單一職責原則

就一個類而言,應該僅有一個引起它變化的原因。在 JavaScript 中,需要用到類的場景并不太多,單一職責原則更多地是被運用在對象或者方法級別上,因此本節(jié)我們的討論大多基于對象和方法。

單一職責原則(SRP)的職責被定義為“引起變化的原因”。如果我們有兩個動機去改寫一個方法,那么這個方法就具有兩個職責。每個職責都是變化的一個軸線,如果一個方法承擔了過多的職責,那么在需求的變遷過程中,需要改寫這個方法的可能性就越大。

此時,這個方法通常是一個不穩(wěn)定的方法,修改代碼總是一件危險的事情,特別是當兩個職責耦合在一起的時候,一個職責發(fā)生變化可能會影響到其他職責的實現(xiàn),造成意想不到的破壞,這種耦合性得到的是低內(nèi)聚和脆弱的設(shè)計。

因此,SRP 原則體現(xiàn)為:一個對象(方法)只做一件事情。

設(shè)計模式中的SRP原則

SRP 原則在很多設(shè)計模式中都有著廣泛的運用,例如代理模式、迭代器模式、單例模式和裝飾者模式。

代理模式

通過增加虛擬代理的方式,把預加載圖片的職責放到代理對象中,而本體僅僅負責往頁面中添加 img 標簽,這也是它最原始的職責。

myImage 負責往頁面中添加 img 標簽:

const myImage = (function () {
	const imgNode = document.createElement('img');
	document.body.appendChild(imgNode);
	return {
		setSrc: function (src) {
			imgNode.src = src;
		}
	}
})();

proxyImage 負責預加載圖片,并在預加載完成之后把請求交給本體 myImage

const proxyImage = (function () {
	const img = new Image;
	img.onload = function () {
		myImage.setSrc(this.src);
	}
	return {
		setSrc: function (src) {
			myImage.setSrc('file:// /C:/Users/svenzeng/Desktop/loading.gif');
			img.src = src;
		}
	}
})();
proxyImage.setSrc('http:// imgcache.qq.com/music/photo/000GGDys0yA0Nk.jpg');

把添加 img 標簽的功能和預加載圖片的職責分開放到兩個對象中,這兩個對象各自都只有一個被修改的動機。在它們各自發(fā)生改變的時候,也不會影響另外的對象。

迭代器模式

我們有這樣一段代碼,先遍歷一個集合,然后往頁面中添加一些 div,這些 divinnerHTML 分別對應集合里的元素:

const appendDiv = function (data) {
	for (let i = 0, l = data.length; i < l; i++) {
		const div = document.createElement('div');
		div.innerHTML = data[i];
		document.body.appendChild(div);
	}
};
appendDiv([1, 2, 3, 4, 5, 6]);

這其實是一段很常見的代碼,經(jīng)常用于 ajax 請求之后,在回調(diào)函數(shù)中遍歷 ajax 請求返回的數(shù)據(jù),然后在頁面中渲染節(jié)點。

appendDiv 函數(shù)本來只是負責渲染數(shù)據(jù),但是在這里它還承擔了遍歷聚合對象 data 的職責。 我們想象一下,如果有一天 api 返回的 data 數(shù)據(jù)格式從 array 變成了 object,那我們遍歷 data 的代碼就會出現(xiàn)問題,必須改成 for ( let i in data )的方式,這時候必須去修改 appendDiv 里的代碼,否則因為遍歷方式的改變,導致不能順利往頁面中添加 div 節(jié)點。

我們有必要把遍歷 data 的職責提取出來,這正是迭代器模式的意義,迭代器模式提供了一種方法來訪問聚合對象,而不用暴露這個對象的內(nèi)部表示。

當把迭代聚合對象的職責單獨封裝在 each 函數(shù)中后,即使以后還要增加新的迭代方式,我們只需要修改 each 函數(shù)即可,appendDiv 函數(shù)不會受到牽連,代碼如下:

const each = function (obj, callback) {
	let value,
		i = 0,
		length = obj.length,
		isArray = isArraylike(obj); // isArraylike 函數(shù)這里未實現(xiàn)
	if (isArray) { // 迭代類數(shù)組
		for (; i < length; i++) {
			callback.call(obj[i], i, obj[i]);
		}
	} else {
		for (i in obj) { // 迭代 object 對象
			value = callback.call(obj[i], i, obj[i]);
		}
	}
	return obj;
};
const appendDiv = function (data) {
	each(data, function (i, n) {
		const div = document.createElement('div');
		div.innerHTML = n;
		document.body.appendChild(div);
	});
};
appendDiv([1, 2, 3, 4, 5, 6]);
appendDiv({ a: 1, b: 2, c: 3, d: 4 });

單例模式

JavaScript單例模式實現(xiàn)過一個惰性單例,最開始的代碼是這樣的:

const createLoginLayer = (function () {
	let div;
	return function () {
		if (!div) {
			div = document.createElement('div');
			div.innerHTML = '我是登錄浮窗';
			div.style.display = 'none';
			document.body.appendChild(div);
		}
		return div;
	}
})();

現(xiàn)在我們把管理單例的職責和創(chuàng)建登錄浮窗的職責分別封裝在兩個方法里,這兩個方法可以獨立變化而互不影響,當它們連接在一起的時候,就完成了創(chuàng)建唯一登錄浮窗的功能,下面的代碼顯然是更好的做法:

const getSingle = function (fn) { // 獲取單例
	let result;
	return function () {
		return result || (result = fn.apply(this, arguments));
	}
};
const createLoginLayer = function () { // 創(chuàng)建登錄浮窗
	const div = document.createElement('div');
	div.innerHTML = '我是登錄浮窗';
	document.body.appendChild(div);
	return div;
};
const createSingleLoginLayer = getSingle(createLoginLayer);
const loginLayer1 = createSingleLoginLayer();
const loginLayer2 = createSingleLoginLayer();
alert(loginLayer1 === loginLayer2); // 輸出: true 

何時應該分離職責

SRP 原則是所有原則中最簡單也是最難正確運用的原則之一。

要明確的是,并不是所有的職責都應該一一分離。

一方面,如果隨著需求的變化,有兩個職責總是同時變化,那就不必分離他們。比如在 ajax 請求的時候,創(chuàng)建 xhr 對象和發(fā)送 xhr 請求幾乎總是在一起的,那么創(chuàng)建 xhr 對象的職責和發(fā)送 xhr 請求的職責就沒有必要分開。

另一方面,職責的變化軸線僅當它們確定會發(fā)生變化時才具有意義,即使兩個職責已經(jīng)被耦合在一起,但它們還沒有發(fā)生改變的征兆,那么也許沒有必要主動分離它們,在代碼需要重構(gòu)的時候再進行分離也不遲。

違反 SRP 原則

在人的常規(guī)思維中,總是習慣性地把一組相關(guān)的行為放到一起,如何正確地分離職責不是一件容易的事情。

一方面,我們受設(shè)計原則的指導,另一方面,我們未必要在任何時候都一成不變地遵守原則。在實際開發(fā)中,因為種種原因違反 SRP 的情況并不少見。比如 jQueryattr 等方法,就是明顯違反 SRP 原則的做法。jQueryattr 是個非常龐大的方法,既負責賦值,又負責取值,這對于 jQuery 的維護者來說,會帶來一些困難,但對于 jQuery 的用戶來說,卻簡化了用戶的使用。

在方便性與穩(wěn)定性之間要有一些取舍。具體是選擇方便性還是穩(wěn)定性,并沒有標準答案,而是要取決于具體的應用環(huán)境。

SRP 原則的優(yōu)缺點

SRP 原則的優(yōu)點是降低了單個類或者對象的復雜度,按照職責把對象分解成更小的粒度,這有助于代碼的復用,也有利于進行單元測試。當一個職責需要變更的時候,不會影響到其他的職責。

但 SRP 原則也有一些缺點,最明顯的是會增加編寫代碼的復雜度。當我們按照職責把對象分解成更小的粒度之后,實際上也增大了這些對象之間相互聯(lián)系的難度。

到此這篇關(guān)于JavaScript單一職責原則深入分析的文章就介紹到這了,更多相關(guān)JS單一職責原則內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript制作簡單分頁插件

    JavaScript制作簡單分頁插件

    本文給大家分享的是JavaScript制作的一個兼容IE6+以及主流瀏覽器的分頁插件,非常的不錯,有需要的小伙伴可以參考下
    2016-09-09
  • JavaScript隱式類型轉(zhuǎn)換

    JavaScript隱式類型轉(zhuǎn)換

    JavaScript的數(shù)據(jù)類型是非常弱的(不然不會叫它做弱類型語言了)!在使用算術(shù)運算符時,運算符兩邊的數(shù)據(jù)類型可以是任意的,比如,一個字符串可以和數(shù)字相加
    2016-03-03
  • HTML的select控件美化

    HTML的select控件美化

    本文主要介紹了HTML的select控件美化以及js實現(xiàn)select選擇功能的方法步驟。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • Javascript自定義函數(shù)判斷網(wǎng)站訪問類型是PC還是移動終端

    Javascript自定義函數(shù)判斷網(wǎng)站訪問類型是PC還是移動終端

    如果,能夠判斷出訪問Web網(wǎng)頁的類型(PC還是移動終端)。就可以解決許多絢麗多彩的 Flash效果出不來的問題
    2014-01-01
  • UNiAPP中如何使用render.js繪制高德地圖

    UNiAPP中如何使用render.js繪制高德地圖

    這篇文章主要介紹了UNiAPP中如何使用render.js繪制高德地圖,renderjs是一個運行在視圖層的js。它比WXS更加強大。它只支持app-vue和h5,文中給大家提到了renderjs的主要作用,需要的朋友可以參考下
    2022-05-05
  • 使用uniapp實現(xiàn)發(fā)布朋友圈功能

    使用uniapp實現(xiàn)發(fā)布朋友圈功能

    這篇文章主要介紹了使用uniapp實現(xiàn)發(fā)布朋友圈功能,在文章底部給大家介紹了uniapp?微信小程序分享、分享朋友圈功能,通過頁內(nèi)自定義分享按鈕,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 個人總結(jié)的一些JavaScript技巧、實用函數(shù)、簡潔方法、編程細節(jié)

    個人總結(jié)的一些JavaScript技巧、實用函數(shù)、簡潔方法、編程細節(jié)

    這篇文章主要介紹了個人總結(jié)的一些JavaScript技巧、實用函數(shù)、簡潔方法、編程細節(jié),本文講解了變量轉(zhuǎn)換、取整同時轉(zhuǎn)換成數(shù)值型、日期轉(zhuǎn)數(shù)值、類數(shù)組對象轉(zhuǎn)數(shù)組、進制之間的轉(zhuǎn)換等方法技巧,需要的朋友可以參考下
    2015-06-06
  • JavaScript函數(shù)之call、apply以及bind方法案例詳解

    JavaScript函數(shù)之call、apply以及bind方法案例詳解

    這篇文章主要介紹了JavaScript函數(shù)之call、apply以及bind方法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • JS生成隨機打亂數(shù)組的方法示例

    JS生成隨機打亂數(shù)組的方法示例

    這篇文章主要介紹了JS生成隨機打亂數(shù)組的方法,涉及javascript數(shù)組隨機排序的相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • JavaScript使用cookie

    JavaScript使用cookie

    JavaScript使用cookie...
    2007-02-02

最新評論