最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

【D1n910】學(xué)習(xí)《JavaScript 設(shè)計(jì)模式》(1[1/2]/6)

2021-02-02 11:10 作者:愛交作業(yè)的D1N910  | 我要投稿

正常操作,正常分析,大家好,我是D1n910。

本系列D1n910】學(xué)習(xí)《JavaScript 設(shè)計(jì)模式》(1/6)正式開坑了!

這本書是我很久以前買的,現(xiàn)在在看了《你不知道的JavaScript》等系列以后,再看這些書,就感覺好了很多。思想層面上提高了一點(diǎn)嘛。

我本來想隆重介紹下作者的,但是看到作者現(xiàn)在在開培訓(xùn)班了,我個(gè)人之前參加過UI設(shè)計(jì)的培訓(xùn)班,結(jié)果不是很好,所以這邊就不介紹了。

這些紛紛擾擾,我等不便參與,還是沉浸在學(xué)習(xí)的海洋里吧!


本期我們學(xué)的是 第一篇 面向?qū)ο缶幊?,?1 章 靈活的語言 —— JavaScript

github倉庫地址

https://github.com/D1N910/JavaScript-design-patterns

第一篇 面向?qū)ο缶幊?/span>

第 1 章 靈活的語言 —— JavaScript

1.1、入職第一天

剛剛畢業(yè)的小新入職了大廠前端。



在廠里小新是用原生 JavaScript 開發(fā)代碼的。


今天產(chǎn)品經(jīng)理給小新分配了一個(gè)任務(wù),讓小新去做一個(gè)驗(yàn)證表單功能的任務(wù)。


小新是有2年大學(xué)打代碼任務(wù)的老前端了好吧。


這個(gè)任務(wù)要驗(yàn)證用戶名稱,小新一看,啪,很簡單啊。


馬上用 JavaScript 閃電編寫了下面的內(nèi)容:


function checkName() {

? ? // 檢查用戶名稱

}

function?checkEmail()?{

? ? // 檢查用戶郵箱

}


……


心滿意足地提交了一個(gè) pr (合并代碼申請(qǐng))到團(tuán)隊(duì)項(xiàng)目里。


這時(shí)候負(fù)責(zé)走讀代碼

(走讀代碼:看看代碼有沒有問題,沒問題就合并代碼,有問題就不合并代碼并進(jìn)行討論溝通解決問題)

的阿蛋看了這個(gè) PR。


“寶貝,這個(gè)有問題,你要改一改。你創(chuàng)建了好多個(gè)全局變量。要不得?!?/p>

“啊,這?這是變量,這不是函數(shù)嗎?”

“函數(shù)難道不是變量嗎?”


阿蛋的反問,讓小新?lián)项^了:“函數(shù)怎么會(huì)是變量呢?”


1.2、函數(shù)的另一種形式

阿蛋噼里啪啦地打了這些內(nèi)容

var?checkName =? function ()?{

? ? // 檢查用戶名稱

}

var checkEmail =?function ()?{

? ? // 檢查用戶郵箱

}


……


“你看這樣和你之前的效果是不是一樣的。”


小新?lián)狭藫项^,“是一樣的,但這樣……”


“這樣就要在用的時(shí)候提前說明, 但是這樣就很明顯地發(fā)現(xiàn)你創(chuàng)建了3個(gè)變量,保存了函數(shù)來實(shí)現(xiàn)你的功能,和之前你用 function 定義是一樣的。所以說你也定義了3個(gè)全局變量。


這些用 function 定義的變量和 var 定義的全局變量一樣,也是直接掛在到 window 對(duì)象下的”


阿蛋打開控制臺(tái)給小新看了下面這張圖。小新果然發(fā)現(xiàn)確實(shí)是掛在到 window 對(duì)象下了。


“那這樣會(huì)有啥問題嗎?”


“從功能上來說當(dāng)然是沒問題的。你是一個(gè)人開發(fā)的時(shí)候這么寫沒問題,但是我們是一個(gè)團(tuán)隊(duì) ,你這么寫可能會(huì)影響到別人,別人寫了同樣名稱的變量也會(huì)覆蓋你的功能。如果你寫了大量的方法,那么這類的問題是比較難發(fā)現(xiàn)的?!?/p>


“那如何才能避免呢?”


“你可以把這些方法放到一個(gè)變量里保存,這樣就減少了覆蓋別人或者被覆蓋的風(fēng)險(xiǎn),而且一旦出現(xiàn)這個(gè)問題,也能更快地發(fā)現(xiàn)!”


1.3、用對(duì)象收編變量

對(duì)象,小新知道這個(gè)東西,就是 "{}" 嘛。

“是這么寫嗎”

小新寫了下面的代碼,把變量放到了 CheckObject 對(duì)象里。

var CheckObject =?{

????checkName:??function ()?{

? ? ????// 檢查用戶名稱

????},

????checkEmail:?function ()?{

? ? ????// 檢查用戶郵箱

????}


????……

}



“好啊,妙啊,你還是蠻懂的,這樣我們所有的函數(shù)變成了 CheckObject 對(duì)象下的方法了,用點(diǎn)語法就可以調(diào)用方法啦!比如檢測姓名 CheckObject.checkName() 。只要在原來的調(diào)用方法的基礎(chǔ)上,加上對(duì)象名稱就可以了。”


1.4、對(duì)象的另一種形式

我們也可以用點(diǎn)語法來在對(duì)象里創(chuàng)建方法。不過要先定義 CheckObject 為一個(gè)對(duì)象,在 JavaScript 中,function 也是對(duì)象,所以可以這么做。

var CheckObject = function() {}

CheckObject.checkName = function () {

? ? // 檢查用戶名稱

}


新創(chuàng)建的方法使用方式和之前是一樣的。但是這樣不太方便,別人使用的時(shí)候不能夠復(fù)制一份。


因?yàn)樵谠蹅冞@邊用的話,是希望能夠拷貝來用的,但是目前這個(gè)對(duì)象類在new來復(fù)制的時(shí)候,不能夠復(fù)制上剛剛點(diǎn)語法定義的函數(shù)。


就像這樣


* 實(shí)際上這里感覺蠻怪的,想要做復(fù)制拷貝的話,可以直接用 `{}` ,對(duì)象拷貝下也能用,不過這里是為了引出類的復(fù)制,也 OK,下面就說了這種對(duì)象拷貝的。


1.5、真假對(duì)象

如果只是想簡單復(fù)制,可以放到一個(gè)對(duì)象里返回

var checkObjectAnotherCopy = function () {

? ?return {

? ? ? ?checkObjectAnotherObjctCheckNameAnother: function () {

? ? ? ? ? ?console.log('1.5 真假對(duì)象 function checkObjectAnotherObjctCheckNameAnother already running');

????????}

????}

}

每次調(diào)用這個(gè)方法的時(shí)候,就會(huì)把新對(duì)象返回來的,所以明面上?checkObjectAnotherCopy,實(shí)際上用的都是新的對(duì)象,這樣每個(gè)人在使用時(shí)就互不影響了。


// 返回新對(duì)象

// 使用時(shí)候不會(huì)相互影響

var a = checkObjectAnotherCopy();

a.checkObjectAnotherObjctCheckNameAnother();


1.6、類也可以

上面這種方式創(chuàng)建出來的對(duì)象和原來的對(duì)象checkObjectAnotherCopy沒啥關(guān)系,我們希望創(chuàng)建真正的類。

var CheckObject = function ()?{

? ? this.checkName =?function ()?{

? ? ????// 檢查用戶名稱

????},

? ? this.checkEmail =?function ()?{

? ? ????// 檢查用戶郵箱

????}

}

像上面這樣寫,就創(chuàng)建了一個(gè)構(gòu)建函數(shù),也可以看作是一個(gè)類,可以這個(gè)類來創(chuàng)建對(duì)象。記得要用 new 關(guān)鍵字。


var c = new CheckObject();

c.checkName();

c.checkEmail();


這樣我們都可以對(duì)類實(shí)例話(用類創(chuàng)建對(duì)象),每個(gè)人都會(huì)有一套屬于自己的方法。


1.7、節(jié)約資源,共用同一個(gè)方法

這里的類創(chuàng)建有一個(gè)小的問題,就是每次創(chuàng)建的時(shí)候,內(nèi)部this上掛載的方法都要被重新定義一次,會(huì)造成一定的性能、資源消耗,可以把這些方法掛載到類的原型上。

var?CheckObject?= function () {}

checkObjectp.prototype.checkName=function(){

????console.log('1.7一個(gè)檢測類 function checkNameAnother already running');

}

// 也可以直接在 prototype 配置

checkObjectp.prototype = {

????checkName1: function () {

? ? ? ?????console.log('1.7 一個(gè)檢測類 function checkName1 already running');

? ?????},

????checkName2: function () {

? ????? ? ?console.log('1.7 一個(gè)檢測類 function checkName2 already running');

? ?????},

????checkName3: function () {

? ? ? ?????console.log('1.7 一個(gè)檢測類 function checkName3 already running');

? ?????}

}


這樣的話,后繼定義的對(duì)象都用的同一個(gè)方法了。

原因是因?yàn)檫@里存在 JavaScript 的原型鏈概念,用點(diǎn)語法訪問JS對(duì)象的屬性,如果直接找不到的話,會(huì)去到這個(gè)對(duì)象的原型 prototype 上去找。

這部分的內(nèi)容,可以參考我下面寫的這篇文章。


1.8、鏈?zhǔn)秸{(diào)用方法

我們使用過 JQuery,里面有好騷的操作,就是可以用點(diǎn)語法連續(xù)調(diào)用使用 ??


$('#id').html('hello').animate(...)


這里的原理是因?yàn)槊總€(gè)方法的調(diào)用都會(huì)返回 JQuery 對(duì)象,就完成了這樣的操作,在對(duì)象中的每個(gè)函數(shù)都會(huì)返回一個(gè) this,也就是對(duì)象本身 ??

var checkObjectCdy = {

? ? checkName1 : function () {

? ? ? ? console.log('1.8 方法還可以這樣用 function checkName1 already running');

? ? ? ? return this;//代表對(duì)象本身

? ? },

? ? checkName2 : function () {

? ? ? ? console.log('1.8 方法還可以這樣用? function checkName2 already running');

? ? ? ? return this;? ? ? ??

? ? },

? ? checkName3 : function () {

? ? ? ? console.log('1.8 方法還可以這樣用? function checkName3 already running');

? ? ? ? return this;? ? ? ??

? ? }

}

checkObjectCdy.checkName1().checkName2().checkName3();


我們當(dāng)然也可以用在之前學(xué)的類里來進(jìn)行使用。


var checkObjectCdyP=function(){}

checkObjectCdyP.prototype={

checkName1 : function () {

? ? ? ?console.log('1.8 方法還可以這樣用 原型 function checkName1 already running');

? ? ? ?return this;//代表對(duì)象本身

? ?},

checkName2 : function () {

? ? ? ?console.log('1.8 方法還可以這樣用 原型 function checkName2 already running');

? ? ? ?return this; ? ? ? ?

? ?},

checkName3 : function () {

? ? ? ?console.log('1.8 方法還可以這樣用 原型 function checkName3 already running');

? ? ? ?return this; ? ? ? ?

? ?}

}

//使用的時(shí)候也要聲明

var d = new checkObjectCdyP();

d.checkName1().checkName2().checkName3();


1.9、函數(shù)的祖先

要知道,函數(shù)本身是對(duì)象,它不是孤立的,它實(shí)際上是繼承自 Function 的,所以我們可以通過修改 Function 的 prototype 的方式,讓所有的函數(shù)擁有某個(gè)屬性,像下面這樣


這里我們可以用 instanceof 關(guān)鍵字驗(yàn)證確實(shí)上面的 c 是 Function 的實(shí)例,所以就能用 Function 上的原型方法。

再列舉一種添加函數(shù)內(nèi)自己的統(tǒng)一方法的案例

Function.prototype.addMethod=function(name,fn){

???? this[name]=fn;

}

var method = function(){};


method.addMethod('checkName',function(){

????console.log('1.9 函數(shù)的祖先 抽象出一個(gè)統(tǒng)一添加方法的功能方法 function checkName already running');

})

method.checkName();

不過不推薦用這種方式,因?yàn)檫@回污染 Window 里的原生對(duì)象。


1.10、鏈?zhǔn)教砑雍瘮?shù)方法

使用上面的內(nèi)容可以實(shí)現(xiàn)在給函數(shù)添加方法

//抽象出一個(gè)統(tǒng)一添加方法的功能方法

Function.prototype.addMethod=function(name,fn){

? ?this.prototype[name]=fn;

? ?return this;

}

var method = function(){};

method.addMethod('checkName',function(){

? ?console.log('1.111 鏈?zhǔn)教砑?function checkName already running');

? ?return this;

});

method.checkName().addMethod('checkName2', function() {}).checkName2();


1.11 換一種方式使用方法

我們也可以使用類的形式來調(diào)用方法。像這樣 ??

var m = new method(); // 這個(gè)?method 類是 1.10 的內(nèi)容

m.checkName();


End

通過本章節(jié)的學(xué)習(xí),我們 Javascript 是一門非常靈活的語言,知道了函數(shù)是 Javascript 里的一等公民。


這里給兩個(gè)課后練習(xí):

(1)試著定義一個(gè)可以為函數(shù)添加多個(gè)方法的 addMethod 方法;

(2)試著定義一個(gè)既可以為函數(shù)原型添加方法又可以為其自身添加方法的 addMethod 方法





【D1n910】學(xué)習(xí)《JavaScript 設(shè)計(jì)模式》(1[1/2]/6)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
酒泉市| 崇阳县| 舞钢市| 辽宁省| 天门市| 信宜市| 淳化县| 友谊县| 丹江口市| 兰西县| 沙湾县| 博野县| 房产| 阳新县| 青阳县| 武义县| 遵化市| 滕州市| 永安市| 宣武区| 海阳市| 长春市| 定兴县| 辽阳市| 吉木乃县| 随州市| 汶上县| 大渡口区| 黄冈市| 阳城县| 库伦旗| 新乐市| 江阴市| 康保县| 华坪县| 南京市| 巴彦淖尔市| 宁河县| 绥滨县| 安新县| 纳雍县|