一些對(duì)你有幫助的JavaScript技巧
本文轉(zhuǎn)載自微信公眾號(hào)「TianTianUp」,作者TianTianUp。轉(zhuǎn)載本文請(qǐng)聯(lián)系TianTianUp公眾號(hào)。
前言
大多數(shù)的編程語(yǔ)言都是足夠開(kāi)放的,允許程序員用多種方式來(lái)做類(lèi)似的結(jié)果。
JavaScript也不例外。對(duì)于JavaScript,我們經(jīng)常會(huì)發(fā)現(xiàn),為了一個(gè)相似的結(jié)果,我們可以用多種方式來(lái)做事情,這有時(shí)會(huì)讓人感到困惑。 有些用法比其他替代方法更好。
你如何改變你的JS代碼,讓它更簡(jiǎn)單,更容易閱讀?
如果你在一個(gè)團(tuán)隊(duì)中工作,寫(xiě)出簡(jiǎn)單的代碼是很重要的。因?yàn)槟悴皇窃谡婵罩泄ぷ?,所以你的程序必須容易被你的團(tuán)隊(duì)成員所遵循。每個(gè)人都喜歡干凈的代碼! 學(xué)習(xí)如何讓JavaScript盡可能的不痛苦,是一項(xiàng)寶貴的技能,肯定會(huì)讓你成為辦公室的寵兒。
JS-Tips
控制臺(tái)提示
代碼執(zhí)行時(shí)間
使用 console.time 和 console.timeEnd 來(lái)確定你的代碼有多快(或多慢)?
這是一個(gè)例子:
- console.time('TEST')
- //some random code to be tested
- console.timeEnd('TEST')
風(fēng)格的Loggin
要獲得自定義輸出,我們將像下面那樣添加%c,然后將實(shí)際的CSS作為第二個(gè)參數(shù)。
- console.log('%c AWESOME', 'color: indigo; font-size:100px')
Tables
當(dāng)你想記錄一個(gè)對(duì)象數(shù)組時(shí),console.table將派上用場(chǎng)。
- // x,y,z are objects
- console.table([x, y, z])
堆棧跟蹤日志
如果你想獲得函數(shù)被調(diào)用的堆棧跟蹤,你可以使用 console.trace。
- console.time('TEST')
- //some random code to be tested
- console.timeEnd('TEST')
動(dòng)態(tài)鍵名
超級(jí)有用的提示!
- const key = 'dynamic'
- const obj = {
- dynamic: 'hey',
- [key]: 'howdy'
- }
- obj.dynamic // hey
- obj[key] // howdy
- obj['dynamic'] //hey
- obj.key // howdy
基于回調(diào)的API->promise
為了讓事情變得更干凈、更高效,你可以將回調(diào)(ourCallbackFn)轉(zhuǎn)化為承諾是一個(gè)函數(shù)。
- // we start with this
- async function foo() {
- const x = await something1()
- const y = await something2()
- ourCallbackFn(){
- // ...
- }
- }
- // the transformation
- async function foo() {
- const x = await something1()
- const y = await something2()
- await promiseCallbackFn() //👀
- }
- function promiseCallbackFn() {
- return new Promise((resolve, reject) => {
- ourCallbackFn((err, data) => { //👀
- if (err) {
- reject(err)
- } else {
- resolve(data)
- }
- })
- })
- }
忘記字符串連接,使用模板
使用+操作符將字符串連接在一起以建立一個(gè)有意義的字符串是老式的。此外,用動(dòng)態(tài)值(或表達(dá)式)連接字符串可能會(huì)導(dǎo)致挫折和錯(cuò)誤。
- let name = 'Charlse';
- let place = 'India';
- let isPrime = bit => {
- return (bit === 'P' ? 'Prime' : 'Nom-Prime');
- }
- // string concatenation using + operator
- let messageConcat = 'Mr. ' + name + ' is from ' + place + '. He is a' + ' ' + isPrime('P') + ' member.'
Template literals(或Template strings)允許嵌入表達(dá)式。
它有獨(dú)特的語(yǔ)法,字符串必須用回車(chē)鍵包圍。模板字符串可以包含動(dòng)態(tài)值的占位符。這些值由美元符號(hào)和大括號(hào)(${expression})標(biāo)記。 下面是一個(gè)例子:
- let name = 'Charlse';
- let place = 'India';
- let isPrime = bit => {
- return (bit === 'P' ? 'Prime' : 'Nom-Prime');
- }
- // using template string
- let messageTemplateStr = `Mr. ${name} is from ${place}. He is a ${isPrime('P')} member.`
- console.log(messageTemplateStr);
isInteger
有一個(gè)更簡(jiǎn)單的方法可以知道一個(gè)值是否是一個(gè)整數(shù)。JavaScript的Number API提供了一個(gè)叫做,isInteger()的方法來(lái)達(dá)到這個(gè)目的。它是非常有用的,最好能知道。
- let mynum = 123;
- let mynumStr = "123";
- console.log(`${mynum} is a number?`, Number.isInteger(mynum));
- console.log(`${mynumStr} is a number?`, Number.isInteger(mynumStr));
Output:
- 123 is a number? true
- 123 is a number? false
Value as Number
你有沒(méi)有注意到,event.target.value總是返回一個(gè)字符串類(lèi)型的值,即使輸入框的類(lèi)型是數(shù)字? 是的,請(qǐng)看下面的例子。我們有一個(gè)簡(jiǎn)單的文本框,類(lèi)型為數(shù)字。這意味著它只接受數(shù)字作為輸入。它有一個(gè)事件處理程序來(lái)處理加鍵事件。
- <input type='number' onkeyup="trackChange(event)" />
在事件處理方法中,我們使用event.target.value取出值。但它返回的是一個(gè)字符串類(lèi)型的值?,F(xiàn)在,我將有一個(gè)額外的頭痛問(wèn)題,就是如何將它解析為一個(gè)整數(shù)。如果輸入框接受浮動(dòng)數(shù)(比如,16.56),那么parseFloat()怎么辦?啊,各種各樣的困惑和額外的工作!
- function trackChange(event) {
- let value = event.target.value;
- console.log(`is ${value} a number?`, Number.isInteger(value));
- }
使用event.target.valueAsNumber代替。它以數(shù)字的形式返回值。
- let valueAsNumber = event.target.valueAsNumber;
- console.log(`is ${value} a number?`, Number.isInteger(valueAsNumber));
value-as-number
&& 運(yùn)算符
讓我們考慮一個(gè)情況,我們有一個(gè)布爾值和一個(gè)函數(shù)。
- let isPrime = true;
- const startWatching = () => {
- console.log('Started Watching!');
- }
這段代碼太多,需要檢查布爾條件并調(diào)用函數(shù)。
- if (isPrime) {
- startWatching();
- }
使用(&&)運(yùn)算符的簡(jiǎn)寫(xiě)呢?是的,完全避免使用if語(yǔ)句??岚?
- isPrime && startWatching();
默認(rèn)值使用 ||
如果你想為一個(gè)變量設(shè)置一個(gè)默認(rèn)值,你可以使用 ||
- let person = {name: 'Jack'};
- let age = person.age || 35; // sets the value 35 if age is undefined
- console.log(`Age of ${person.name} is ${age}`);
但是等等,它有一個(gè)問(wèn)題。如果這個(gè)人的年齡是0(可能是剛出生的嬰兒)。年齡將被計(jì)算為35,這是意想不到的行為。
進(jìn)入空值凝聚運(yùn)算符(??)。它是一個(gè)邏輯運(yùn)算符,當(dāng)其左手操作數(shù)為空或未定義時(shí),返回其右手操作數(shù),否則返回其左手操作數(shù)。
要用??運(yùn)算符重寫(xiě)上述代碼。
- let person = {name: 'Jack'};
- let age = person.age ?? 35; // sets the value 0 if age 0, 35 in case of undefined and null
- console.log(`Age of ${person.name} is ${age}`);
Randoms
生成一個(gè)隨機(jī)數(shù)或從數(shù)組中獲取一個(gè)隨機(jī)項(xiàng)目是一個(gè)非常有用的方法,可以隨身攜帶。在我的很多項(xiàng)目中,我都看到它們多次出現(xiàn)。 從一個(gè)數(shù)組中獲取一個(gè)隨機(jī)項(xiàng)目。
- let planets = ['Mercury ', 'Mars', 'Venus', 'Earth', 'Neptune', 'Uranus', 'Saturn', 'Jupiter'];
- let randomPlanet = planets[Math.floor(Math.random() * planets.length)];
- console.log('Random Planet', randomPlanet);
通過(guò)指定最小值和最大值從一個(gè)范圍內(nèi)生成一個(gè)隨機(jī)數(shù)。
- let getRandom = (min, max) => {
- return Math.round(Math.random() * (max - min) + min);
- }
- console.log('Get random', getRandom(0, 10));
函數(shù)默認(rèn)參數(shù)
在JavaScript中,函數(shù)參數(shù)(params)就像該函數(shù)的局部變量。在調(diào)用函數(shù)時(shí),你可以為這些參數(shù)傳值,也可以不傳值。如果你不為param傳值,它將是未定義的,可能會(huì)引起一些不必要的副作用。
在定義函數(shù)參數(shù)時(shí),有一種簡(jiǎn)單的方法可以將默認(rèn)值傳遞給函數(shù)參數(shù)。下面是一個(gè)例子,我們將默認(rèn)值Hello傳遞給問(wèn)候函數(shù)的參數(shù)信息。
- let greetings = (name, message='Hello,') => {
- return `${message} ${name}`;
- }
- console.log(greetings('Jack'));
- console.log(greetings('Jack', 'Hola!'));
所需函數(shù)參數(shù)
在默認(rèn)參數(shù)技術(shù)的基礎(chǔ)上進(jìn)行擴(kuò)展,我們可以將一個(gè)參數(shù)標(biāo)記為強(qiáng)制性的。首先,定義一個(gè)函數(shù)來(lái)拋出一個(gè)帶有錯(cuò)誤信息的錯(cuò)誤。
- let isRequired = () => {
- throw new Error('This is a mandatory parameter.');
- }
然后為所需參數(shù)分配函數(shù)的默認(rèn)值。記住,在調(diào)用時(shí),當(dāng)一個(gè)值作為參數(shù)傳遞時(shí),默認(rèn)值會(huì)被忽略。但是,如果參數(shù)值是未定義的,則會(huì)考慮默認(rèn)值。
- let greetings = (name=isRequired(), message='Hello,') => {
- return `${message} ${name}`;
- }
- console.log(greetings());
在上面的代碼中,name將是未定義的,并且將嘗試為它設(shè)置默認(rèn)值,即isRequired()函數(shù)。它將拋出一個(gè)錯(cuò)誤。
error
逗號(hào)運(yùn)算符
當(dāng)我意識(shí)到逗號(hào)(,)是一個(gè)獨(dú)立的操作符時(shí),我感到很驚訝,而且從來(lái)沒(méi)有注意到它的存在。我一直在代碼中使用它,但是,從來(lái)沒(méi)有意識(shí)到它的真正存在。
在JavaScript中,逗號(hào)(,)運(yùn)算符用于從左到右評(píng)估每個(gè)操作數(shù),并返回最后一個(gè)操作數(shù)的值。
- let count = 1;
- let ret = (count++, count);
- console.log(ret);
在上面的例子中,變量ret的值將是,2.同樣的,下面代碼的輸出將把32的值記錄到控制臺(tái)。
- let val = (12, 32);
- console.log(val);
我們用在哪里?有什么猜測(cè)嗎?逗號(hào)(,)運(yùn)算符最常見(jiàn)的用法是在for循環(huán)中提供多個(gè)參數(shù)。
- for (var i = 0, j = 50; i <= 50; i++, j--)
合并多個(gè)對(duì)象
您可能需要將兩個(gè)對(duì)象合并在一起,并創(chuàng)建一個(gè)更好的信息對(duì)象來(lái)工作。你可以使用展開(kāi)運(yùn)算符......(是的,三個(gè)點(diǎn)!)。 考慮兩個(gè)對(duì)象,分別是emp和job。
- let emp = {
- 'id': 'E_01',
- 'name': 'Jack',
- 'age': 32,
- 'addr': 'India'
- };
- let job = {
- 'title': 'Software Dev',
- 'location': 'Paris'
- };
使用價(jià)差運(yùn)算符將它們合并為:
- // spread operator
- let merged = {...emp, ...job};
- console.log('Spread merged', merged);
有另一種方法來(lái)執(zhí)行這種合并。使用Object.assign()。你可以這樣做。
- console.log('Object assign', Object.assign({}, emp, job));
結(jié)果:
合并對(duì)象
注意,spread操作符和Object.assign都是執(zhí)行淺層合并。在淺層合并中,第一個(gè)對(duì)象的屬性會(huì)被覆蓋到與第二個(gè)對(duì)象相同的屬性值。 對(duì)于深合并,請(qǐng)使用類(lèi)似于:_merge of lodash。
解構(gòu)
將數(shù)組元素和對(duì)象屬性分解為變量的技術(shù)稱(chēng)為,反結(jié)構(gòu)。讓我們通過(guò)幾個(gè)例子來(lái)看看。
數(shù)組
在這里,我們有一系列的表情符號(hào),
- let emojis = ['🔥', '⏲️', '🏆', '🍉'];
要解構(gòu),我們將使用如下語(yǔ)法。
- let [fire, clock, , watermelon] = emojis;
這和做,讓火=表情符號(hào)[0]是一樣的;但多了很多靈活性。 你有沒(méi)有注意到,我只是用中間的空位忽略了獎(jiǎng)杯表情?那么這樣做的輸出會(huì)是什么呢?
- console.log(fire, clock, watermelon);
結(jié)果:
讓我在這里也介紹一下叫做 rest 操作符的東西。如果你想對(duì)一個(gè)數(shù)組進(jìn)行重構(gòu),將一個(gè)或多個(gè)項(xiàng)目賦值給變量,然后將其余的項(xiàng)目存入另一個(gè)數(shù)組,你可以使用......休息運(yùn)算符來(lái)實(shí)現(xiàn),如下圖所示。
- let [fruit, ...rest] = emojis;
- console.log(rest);
結(jié)果:
對(duì)象
和數(shù)組一樣,我們也可以對(duì)對(duì)象進(jìn)行重構(gòu)。
- let shape = {
- name: 'rect',
- sides: 4,
- height: 300,
- width: 500
- };
破壞結(jié)構(gòu),我們得到一個(gè)名字,邊在幾個(gè)變量中,其余的在另一個(gè)對(duì)象中。
- let {name, sides, ...restObj} = shape;
- console.log(name, sides);
- console.log(restObj);
結(jié)果:
獲取查詢(xún)參數(shù)
window.location對(duì)象有一堆實(shí)用的方法和屬性,我們可以通過(guò)這些屬性和方法來(lái)獲取瀏覽器URL的協(xié)議、主機(jī)、端口、域名等信息。我們可以通過(guò)這些屬性和方法從瀏覽器的URL中獲取協(xié)議、主機(jī)、端口、域名等信息。
我發(fā)現(xiàn)非常有用的屬性之一是,
- window.location.search
搜索屬性從位置URL中返回查詢(xún)字符串。下面是一個(gè)示例URL:https:/tapasadhiary.com?project=js。location.search將返回,?project=js。
- let project = new URLSearchParams(location.search).get('project');
結(jié)果:
- js
最后
我真的希望你能學(xué)到一些新的技巧??茨隳馨汛a寫(xiě)得多小多清晰,是一件很有趣的事。
原文鏈接:https://mp.weixin.qq.com/s/h6gwuaCQbPUdEonjH5Gjbw




























