
、
英文 | https://javascript.plainenglish.io/42-tips-and-tricks-to-write-faster-better-optimized-javascript-code-3a82c53d051e
翻譯 | web前端開發
我一直喜歡報紙之類的東西,可以在較短的時間内提供足夠的資訊。在這裡,我為前端開發優化建立了一個新的學習清單。
你可能已經進行了很長時間的JavaScript開發,但是,有的最新功能與開發技巧,你可能沒有使用過。今天這篇文章就是幫助你解決一些JavaScript中的新問題新技巧。
在這裡,我分享了42個技巧,這些技巧對我的日常開發程式設計工作很有幫助,也希望這些技巧對你也有所幫助。
1、按字元串屬性值對對象數組進行排序
可以通過不同的方式來完成。
1)、使用Underscore
_.sortBy(collection, [iteratees=[_.identity]])
建立一個元素數組,并按照在每個Iteratee中運作集合中每個元素的結果,以升序排序。此方法執行穩定的排序,即保留相等元素的原始排序順序。疊代對象由一個參數(value)調用。
var objs = [
{ val1: 'abc',val2: 'a' },
{ val1: 'cde', val2: 'b' },
{ val1: 'fgh', val2: 'c' }
];
var sortedValues = _.sortBy( objs, 'val1' );
2)、使用ES6排序功能
var data = [
{ name: 'abc', value: 21 },
{ name: 'cde', value: 37 },
{ name: 'ee', value: 45 },
{ name: 'ff', value: -12 },
{ name: 'ab', value: 13 },
{ name: 'cs', value: 37 }
];
// sort by value
data.sort(function (a, b) {
return a.value - b.value;
});
3)、使用Lodash
const sortedValues = _.sortBy(data, 'string');
2、如何四舍五入至小數點後兩位(僅在必要時)?
我們可以通過3種不同的方式來實作此功能。
在跳轉到解決方案之前,讓我們先了解一些定義。
該parseFloat()函數解析一個參數(如果需要,首先将其轉換為字元串)并傳回一個浮點數。
該toFixed()方法使用定點表示法格式化數字。
1)、使用ParseFloat
parseFloat("183.456").toFixed(2);
該Math.round()函數傳回四舍五入到最接近的整數的數字的值。
2)、使用MathRound
Math.round( num * 100 + Number.EPSILON ) / 100
Number()建立一個新Number值。
3)、将字元串轉換為十進制
var string = 10.134.toFixed(2); // => '10.13'
var num = Number(string); // => 10.13
3、如何周遊或枚舉JavaScript對象?
每個ECMAScript版本都采用不同的方式枚舉對象。讓我們檢查一下。
該Object.keys()方法傳回給定對象自己的可枚舉屬性名稱的數組,并以與普通循環相同的順序進行疊代。
該forEach()方法為每個數組元素執行一次提供的功能。
ES5(Object.keys()和forEach)
var data = { val1: "abc", val2: "cde" };
Object.keys(data).forEach(function(key) {
console.log(key, obj[key]);
});
ES6(for ... of):
該for...of語句在建立了一個循環疊代疊代的對象,包括:内置String,Array,陣列狀物體(例如,arguments或NodeList), TypedArray,Map,Set和使用者定義的iterables。它使用對象的每個不同屬性的值調用要執行的語句來調用自定義疊代挂鈎。
for (const key of Object.keys(data)) {
console.log(key, obj[key]);
}
ES8 Object.entries()
該Object.entries()方法傳回給定對象自己的可枚舉字元串鍵屬性[key, value]對的數組,其順序與for...in循環提供的順序相同。
Object.entries(data).forEach(
([key, value]) => console.log(key, value)
);
我們可以合并for...of,銷毀和Object.entries:
for (const [key, value] of Object.entries(data)) {
console.log(key, value);
}
4、event.preventDefault()和return false有什麼差別?
如果傳回false,則有可能正在執行其他函數,這些函數是專門在click内編寫的,而preventDefault則不允許執行任何操作。
$('a').click(function (e) {
// logic
// runtime error...navigation happened
return false;
});
preventDefault()的示例
$('a').click(function (e) {
e.preventDefault();
// logic
// runtime error, naviagation will not happen
});
5、如何檢查JavaScript中的空字元/未定義字元串/空字元串?
if (!!data) {
// Some code here
}
或使用類型轉換:
if (Boolean(data)) {
// Code here
}
兩者執行相同的功能。将變量類型轉換為布爾值,其中str是變量。
對于null,undefined,0、000,“ ”,false,它将傳回false。
對于字元串“ 0”和“空格 ”,它傳回true。
6、如何将項目插入到特定索引(JavaScript)的數組中?
在特定索引處附加單個元素
//Append at index 2
array.splice(2, 0,'newData');
//Append at index 5
array[5] = 'newData';
在特定索引處附加多個元素。
//Append at index 2
array.splice(2, 0,'data1', 'data2', 'data3');
7、如何使用JavaScript擷取目前URL?
使用windows功能:window.location.href
8、檢查密鑰是否存在于JavaScript對象中?
在操作符中使用。
let data =“ abc” in array;
使用hasOwnProperty
let result = data.hasOwnProperty("abc")
直接通路元素(括号樣式)
let result = data["abc"] === undefined
直接通路元素(對象樣式)
let result = array.abc === undefined;
9、如何在JavaScript中合并兩個數組并删除重複項?
我們确實在日常生活中使用數組,并且有很多要求,我們需要組合數組以及删除重複項。
以下是實作此目的的一些方法。
1)、使用Lodash
console.log(_.union([10, 4, 5], [134, 26, 19, 10], [6, 1]));
2)、使用Filter和Concat
let a = [56, 43, 3], b = [11, 43, 56, 12]
let c = a.concat(b)
let d = c.filter((val, pos) => c.indexOf(val) === pos)
3、使用set
[...new Set([...array1 ,...array2])]; // => remove duplication
10、如何檢查字元串在JavaScript中是否包含子字元串?
我們可以使用以下兩種方法來實作此功能。
1)、includes()
該includes()方法确定一個數組是否在其條目中包括某個值,是傳回值true還是false适當的值。
const val1 = "atitpatel";
const val2 = "patel";
console.log(string.includes(val2));
2)、indexof()
在indexOf()該方法傳回在該給定元素可以在陣列中可以發現,或-1,如果它不存在的第一個索引。
var str = "atitpatel";
var substr = "patel";
console.log(str.indexOf(substr) !== -1);
11、如何替換所有出現的字元串
1)、我們可以使用ES6來解決這個問題。
str = str.replace(/test/g, '');
2)、我們可以使用正規表達式。
let find = 'ab';
let re = new RegExp(find, '');
let str = find.replace(re, 'cd');
console.log(str);
12、如何正确克隆JavaScript對象
1)、使用ES6
var val1 = {data: "value"};
var val2= Object.assign({}, val1);
2)、如果要淺拷貝
Object.assign({}, data)
3)、進行深複制
JSON.parse(JSON.stringify(data))
13、!!不是JavaScript中的運算符?
!! 将其右側的值轉換為其等效的布爾值。
!!false === false
!!true === true
!!0 === false
!!parseInt("foo") === false // NaN is falsy
!!1 === true
!!-1 === true // -1 is truthy
!!(1/0) === true // Infinity is truthy
!!"" === false // empty string is falsy
!!"foo" === true // non-empty string is truthy
!!"false" === true // ...even if it contains a falsy value
!!window.foo === false // undefined is falsy
!!null === false // null is falsy
!!{} === true // an (empty) object is truthy
!![] === true // an (empty) array is truthy;
14、如何在JavaScript中循環周遊數組?
我們有幾種選擇:
1)、順序for循環:
var array = ["a","b"];
var arrayLength = array.length;
for (var i = 0; i < arrayLength; i++) {
console.log("value",array[i]);
}
2)、Array.prototype.forEach
const data = ["a", "b", "c"];
data.forEach(function (item, index) {
console.log(item, index);
});
3)、 ES6for-of聲明
let data = ['a', 'b', 'c'];
for (const a of data){
console.log(a);
}
15、如何使用JavaScript複制到剪貼闆
通過執行以下操作,我們可以提示使用者單擊并輸入:
function copy(text) {
window.prompt("Copy to clipboard: Ctrl+C, Enter", text);
}
現在,剪貼闆複制操作為SAFE,因為使用者單擊了提示。
<button id="data" onclick="copy(document.getElementById('data').innerHTML)">Copy here</button>
<script>
function copy(text) {
window.prompt("To Copy Please do this: Ctrl+C, Enter", text);
}
</script>
16、如何測試一個空的JavaScript對象
有幾種方法可以實作此功能。
1)、jQuery的:
jQuery.isEmptyObject({}); // true
2)、 lodash:
_.isEmpty({}); // true
3)、Underscore
_.isEmpty({}); // true
17、如何在JavaScript中使字元串的首字母大寫
我們可以更新具有text-transform屬性的CSS。
1)、在CSS中:
p:first {
text-transform:capitalize;
}
2)、使用函數,我們可以調用toUpperCase()方法。
function makeUpperCase(val)
{
return val && val[0].toUpperCase() + val.slice(1);
}
18、如何使用JavaScript更改元素的類?
有很多需求,我們需要根據條件更改某些顔色或CSS。
如何在JavaScript中完成?
更改元素的所有類:
要将所有現有類替換為一個或多個新類,請設定className屬性:
document.getElementById("test").className = "newclass";
要将其他類添加到元素:
要将類添加到元素中而不删除或影響現有值,請添加空格和新的類名稱,如下所示:
document.getElementById("test").className += " newClass";
要從元素中删除類:
要在元素中删除單個類而又不影響其他潛在類,則需要簡單的正規表達式替換:
document.getElementById("test").className =
document.getElementById("test").className.replace
( /(?:^|\s)newClass(?!\S)/g , '' )
19、是否可以将CSS應用于一半的字元?
我們确實看到了一些精美的文字藝術,其中一半字元具有不同的顔色,而另一半字元具有不同的顔色,我們如何在CSS中實作這樣的效果?
下面是使CSS适用于半角字元的示例。
h1 {
display: inline-block;
margin: 0; /* for demo snippet */
line-height: 1em; /* for demo snippet */
font-family: helvetica, arial, sans-serif;
font-weight: bold;
font-size: 300px;
background: linear-gradient(to right, #7db9e8 50%,#1e5799 50%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
<h1>XYZ</h1>
20、如何在數組中追加内容?
在較早的JavaScript版本中,這是通過使用apply方法完成的。
該apply()方法調用具有給定this值的函數,并arguments以數組(或類似數組的對象)的形式提供。
let array1 = [33, 45, 5];
let array2 = [100, 2];
Array.prototype.push.apply(array2, array1);
console.log(array2); // [100, 2, 33, 45, 5]
使用ES6,可以使用擴充運算符完成此操作。
let array1 = [11, 42, 53];
let array2 = [1, 2];
array2.push(...array1);
console.log(array2); // [11, 2, 3, 42, 53]
21、如何檢查對象是否為數組?
當我們想檢查對象是否為數組時,可以遵循以下選項。
let arr = [10,20,30,40,50];
Javascript(新舊浏覽器):
function isArray(arr) {
return arr.constructor.toString().indexOf("Array") > -1;
}
function isArray(arr) {
return arr instanceof Array;
}
function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
}
然後這樣稱呼它:
isArray(arr);
JavaScript(IE9 +,Ch5 +,FF4 +,Saf5 +,Opera10.5 +)
Array.isArray(arr);
下劃線和Lodash:
_.isArray(arr);
22、如何檢測未定義的對象屬性?
當我們想檢查對象的特定屬性是否未定義時,我們可以直接使用if條件和===運算符進行檢查。
if(data.prop === undefined) {
alert("it is: `undefined`");
}
要檢查對象是否實際上沒有這樣的屬性,并嘗試通路它時,預設情況下将傳回undefined:
if(!o.hasOwnProperty('prop')) {
alert("not exisiting);
}
檢查與辨別符關聯的值是否為特殊值undefined,或者尚未聲明該辨別符。
if(typeof variable === 'undefined') {
alert('variable is `undefined`, or it is not declared');
}
23、如何在JavaScript中将字元串轉換為布爾值?
有幾種方法可以在JavaScript中将字元串轉換為布爾值。
使用測試方法
var stringValue = "true";
var boolValue = (/true/i).test(stringValue) //returns true
使用比較運算符
var val = "true";
var boolValue = (val =="true"); //returns true
使用JSON.parse
var val = "true";
var boolValue = JSON.parse(val); //returns true
使用三元運算符
var val = “true”;
var boolValue = val.toLowerCase() == ‘true’ ? true : false; //returns true
使用 switch-case
var val = "true";
var boolValue = getBoolean(val); //returns true
function getBoolean(value){
switch(value){
case true:
case "true":
case 1:
case "1":
case "on":
case "yes":
return true;
default:
return false;
}
}
24、如何擷取JavaScript中的查詢字元串值?
當我們處理URL參數并想從URL中提取資訊時,這是最常見的用法。
下面是一些我們可以從中擷取字元串值的方法。
ES2015(ES6):建立一種實作此功能的方法
getQueryStringParams = query => {
return query
? (/^[?#]/.test(query) ? query.slice(1) : query)
.split('&')
.reduce((params, param) => {
let [key, value] = param.split('=');
params[key] = value ? decodeURIComponent(value.replace(/\+/g, ' ')) : '';
return params;
}, {}
)
: {}
};
URLSearchParams從位置使用内置方法。
你可以在location以下位置使用它:
let params = new URLSearchParams(location.search);
let params = (new URL(location)).searchParams;
let url = new URL('https://abc.com?val1=1&val2=2');
let params = new URLSearchParams(url.search);
我們還可以使用.searchParamsURL對象的簡寫屬性來擷取參數,如下所示:
let params = new URL('https://abc.com?val1=1&val2=2').searchParams;
params.get('val1'); // "1"
params.get('val2'); // "2"
25、如何擷取JavaScript對象的長度?
在大多數情況下,我們确實檢查數組的長度,但是,如果要檢查對象的長度怎麼辦?以下兩種方法是擷取對象長度的最佳方法。
1、使用ES6功能
let size = Object.keys(data).length;
2、使用下劃線
_.size({val1 : 1, val2 : 2, val3 : 3});
26、如何反轉包含複雜表情符号的字元串?
當我們進行更多程式設計或遇到一些編碼挑戰時,這是其中最常見的問題。
我們可以使用lodash功能來解決這一挑戰。
function reverse(txt) { return _.split(txt, '').reverse().join(''); }
const data = 'abc abc👩🦰👩👩👦👦';
console.log(reverse(data));
27、如何在JavaScript中将字元串轉換為對象數組?
當我們從無法控制的第三方API中擷取一些資料時,就會出現這種情況。我們如何将字元串轉換為對象數組以在我們的應用程式中使用?下面是實作此結果的最簡單方法
const str = 'Option 1|false|Option 2|false|Option 3|false|Option 4|true';
data = [];
for (let i = 0, a= str.split('|'); i < a.length; i += 2) {
const
option = a[i],
value = JSON.parse(a[i + 1]);
data.push({ option, value });
}
console.log(data);
28、如何檢測使用者是否更改了JavaScript中的頁籤?
這可以通過JavaScript支援的最新事件偵聽器功能來實作。
下面是處理頁籤狀态的解決方案。
document .addEventListener("visibilitychange", event => {
if (document.visibilityState == "visible") {
console.log("activated")
} else {
console.log("inactivated")
}
})
29、如何從一個對象數組求和一個屬性值?
當我們有一個包含一些數字的對象數組時,我們想在下面求和是帶有reduce的解決方案。
const data = [
{ val1: 'abc', val2: 50 },
{ val1: 'abc', val2: 50 },
{ val1: 'cde', val2: 75 },
{ val1: 'hji', val2: 35 },
{ val1: 'bbc', val2: 25 },
];
console.log(data.reduce((n, {val2}) => n + val2, 0))
30、如何格式化JavaScript日期?
當我們格式化日期時,更令人頭疼,因為我們确實根據需求有不同的要求。我們如何才能滿足每個人的需求?以下是廣泛用于在JavaScript中格式化日期的最常用方法。
1)、你可以使用本機 .toLocaleDateString()
例子:
new Date().toLocaleDateString() // 1/06/2021
new Date().toLocaleDateString('en-US', {year: 'numeric', month: '2-digit', day: '2-digit'}); // 01/06/2021 (month and day with two digits)
new Date().toLocaleDateString('en-ZA'); // 2020/01/06(year/month/day) notice the different locale
new Date().toLocaleDateString('en-CA'); // 2021-01-06 (year-month-day) notice the different locale
new Date().toLocaleString("en-US", {hour: '2-digit', hour12: false, timeZone: "America/New_York"}); // 07 (just the hour)
2)、我們可以使用moment.js
var now = new Date();
var dateString = moment(now).format('YYYY-MM-DD');
var dateStringWithTime = moment(now).format('YYYY-MM-DD HH:mm:ss');
31、如何在JavaScript中生成随機字元串/字元?
很多時候,我們需要向後端發送一些随機的唯一ID。實作此功能的解決方案有成千上萬種,但以下是我最喜歡的一種。
生成一個安全的随機字母數字Base-62字元串:
function generateUID(length)
{
return window.btoa(Array.from(window.crypto.getRandomValues(new Uint8Array(length * 2))).map((b) => String.fromCharCode(b)).join("")).replace(/[+/]/g, "").substring(0, length);
}
console.log(generateUID(22)); // "cFg3Upv2cE5cK8Xd7hHwWp"
console.log(generateUID(5)); // "CAGkP"
32、在字段中輸入3個字元後如何執行API調用?
當我們要搜尋使用者名或某個已經存在的值但又要避免一直調用時,我們經常要等到使用者鍵入某些字元後再調用API,這是最常用的方法。
這可以使用distinctUntilChanged來實作,并且你可以使用filter。
this.service.getData(data)
.pipe(
filter(_ => data.length === 3),
distinctUntilChanged()
).subscribe(rs => console.log(rs));
33、如何重命名數組内的對象鍵?
有時我們需要更改鍵來操作資料。這是在數組中重命名對象鍵的有效方法之一。
你可以使用Object.values()它來檢索值,然後array.reduce()組成一個新的對象:
const data = [{
prop_name: 'test1',
prop_age: 45,
prop_email: '[email protected]',
},
{
prop_name: 'test2',
prop_age: 41,
prop_email: '[email protected]',
},
{
prop_name: 'test3',
prop_age: 45,
prop_email: '[email protected]',
},
];
const newKey = [
'firstname',
'age',
'email'
];
let resultData = data.map(obj =>
Object.values(obj).reduce((acc, cur, i) => {
acc[newKey[i]] = cur;
return acc;
}, {}));
console.log(resultData);
34、如何清除javascript中的焦點?
焦點…焦點…是的,這一次,我們想從HTML中的特定元素中清除焦點。這可以通過模糊方法來實作。
if (document.activeElement instanceof HTMLElement)
document.activeElement.blur();
35、JavaScript中的二進制到字元串
如果我們有一些二進制代碼,并且想要在将其用于代碼之前将其轉換為字元串,該怎麼辦?可以使用fromCharCode方法實作。
let binary = `1010011 1110100 1100001 1100011 1101011
1001111 1110110 1100101 1110010 1100110
1101100 1101111 1110111`;
let newData = binary.split(' ') //Split string in array of binary chars
.map(bin => String.fromCharCode(parseInt(bin, 2))) //Map every binary char to real character
.join(''); //Join the array back to a string
console.log(newData);
36、移位字元串在JavaScript中向左和向右循環
這種javascript編碼問題很常見。這是基于給定值移動字元串的示例。可以使用數組切片方法來實作。
function getShiftedString(s, leftShifts, rightShifts) {
// using `split('')` will result in certain unicode characters being separated incorrectly
// use Array.from instead:
const arr = Array.from(s);
const netLeftShifts = (leftShifts - rightShifts) % arr.length;
return [...arr.slice(netLeftShifts), ...arr.slice(0, netLeftShifts)]
.join('');
}
console.log([
getShiftedString('abc', 0, 0),
getShiftedString('abc', 1, 0),
getShiftedString('abc', 0, 1),
getShiftedString('abc', 1, 1),
getShiftedString('123456789', 0, 0),
getShiftedString('123456789', 1, 5),
getShiftedString('123456789', 5, 1),
'----',
getShiftedString('123456789', 9, 0),
getShiftedString('123456789', 10, 0),
getShiftedString('123456789', 0, 9),
getShiftedString('123456789', 0, 10),
getShiftedString("🐎👱❤", 0, 0),
getShiftedString("🐎👱❤", 1, 0),
]);
37、檢查IP位址的正規表達式JavaScript
正規表達式可幫助我們檢查任何特定的字元串并為我們驗證?如果我們要使用正規表達式作為IP位址該怎麼辦。我在這裡喜歡Mahdi Pedram解決方案來實作這一目标。
這是驗證IP位址的最幹淨的方法,下面将其分解:
事實:一個有效的IP位址具有4 octets,每個八位位元組可以是一個介于0 - 255
正規表達式的細分,該正規表達式比對之間的任何值 0 - 255
- 25[0-5] matches 250 - 255
- 2[0-4][0-9] matches200 - 249
- 1[0-9][0-9] matches 100 - 199
- [1-9][0-9]? matches 1 - 99
- 0 matches 0
const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';
注意:使用new RegExp時應使用\\.而不是\.因為字元串将被轉義兩次。
function isValidIP(str) {
const octet = '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)';
const regex = new RegExp(`^${octet}\\.${octet}\\.${octet}\\.${octet}$`);
return regex.test(str);
}
38、如何用JSON對JavaScript日期進行字元串化并保留時區
當我們要将任何特定的日期格式值存儲到JSON時。使用此功能可以實作。
var changeValue = function(key, value) {
if (this[key] instanceof Date) {
return this[key].toUTCString();
}
return value;
}
console.log(JSON.stringify(new Date(), changeValue));
console.log(JSON.stringify({ myProperty: new Date()}, changeValue));
39、JavaScript檢查字元串是否為有效數字
我們已經看到了很多解決方案來檢查數字是否有效,但是如果要檢查字元串是否是有效數字怎麼辦?
這是最好的方法。
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
以下是一些很好的測試用例:
console.log(isNumeric(123456898898912345678912)); // true
console.log(isNumeric('2 ')); // true
console.log(isNumeric('-42.2 ')); // true
console.log(isNumeric(-562.2)); // true
console.log(isNumeric(undefined)); // false
console.log(isNumeric('')); // false
console.log(isNumeric(null)); // false
console.log(isNumeric([])); // false
40、将JSON對象導出到文本檔案
當我們要将JSON對象導出到文本檔案時,以下是我從NutCracker答案中發現的最幹淨的方法。
const filename = 'data.json';
const jsonStr = JSON.stringify(JsonExport);
let element = document.createElement('a');
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(jsonStr));
element.setAttribute('download', filename);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
41、将長模闆文字行換行為多行,而不在字元串中建立新行
如果您在文字中新行的點處引入換行符(\),則不會在輸出中建立新行:
const text = `abc abc abc abc abc abc abc\
and abc and abc`;
console.log(text);
42、如何将文本從div複制到剪貼闆
當我們要将文本從div複制到下面的剪貼闆時,這是我從StackOverflow romin21答案中找到的最簡單的方法。
function CopyToClipboard(containerid) {
if (window.getSelection) {
if (window.getSelection().empty) { // Chrome
window.getSelection().empty();
} else if (window.getSelection().removeAllRanges) { // Firefox
window.getSelection().removeAllRanges();
}
} else if (document.selection) { // IE?
document.selection.empty();
}
if (document.selection) {
var range = document.body.createTextRange();
range.moveToElementText(document.getElementById(containerid));
range.select().createTextRange();
document.execCommand("copy");
} else if (window.getSelection) {
var range = document.createRange();
range.selectNode(document.getElementById(containerid));
window.getSelection().addRange(range);
document.execCommand("copy");
}
}
總結
到這裡,我分享的42個JavaScript的技巧就全部結束了,希望,這個對你有所幫助。