1.遍歷數(shù)組法
網(wǎng)站建設哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設計、網(wǎng)站建設、微信開發(fā)、小程序制作、集團企業(yè)網(wǎng)站建設等服務項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了新晃免費建站歡迎大家使用!
最簡單的去重方法, 實現(xiàn)思路:新建一新數(shù)組,遍歷傳入數(shù)組,值不在新數(shù)組就加入該新數(shù)組中;注意點:判斷值是否在數(shù)組的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,需多寫一些兼容低版本瀏覽器代碼,源碼如下:
// 最簡單數(shù)組去重法
function unique1(array){
var n = []; //一個新的臨時數(shù)組
//遍歷當前數(shù)組
for(var i = 0; i array.length; i++){
//如果當前數(shù)組的第i已經(jīng)保存進了臨時數(shù)組,那么跳過,
//否則把當前項push到臨時數(shù)組里面
if (n.indexOf(array[i]) == -1) n.push(array[i]);
}
return n;
}
// 判斷瀏覽器是否支持indexOf ,indexOf 為ecmaScript5新方法 IE8以下(包括IE8, IE8只支持部分ecma5)不支持
if (!Array.prototype.indexOf){
// 新增indexOf方法
Array.prototype.indexOf = function(item){
var result = -1, a_item = null;
if (this.length == 0){
return result;
}
for(var i = 0, len = this.length; i len; i++){
a_item = this[i];
if (a_item === item){
result = i;
break;
}
}
原生js的數(shù)組是不包含去重函數(shù)的。
可以自己編寫去重函數(shù)。
下面是一個簡單的例子
$.array.extend({
unique?:?function?(fn)?{
var?len?=?this.length,
result?=?this.slice(0),
i,?datum;
if?('function'?!=?typeof?fn)?{
fn?=?function?(item1,?item2)?{
return?item1?===?item2;
};
}
while?(--len??0)?{
datum?=?result[len];
i?=?len;
while?(i--)?{
if?(fn(datum,?result[i]))?{
result.splice(len,?1);
break;
}
}
}
len?=?this.length?=?result.length;
for?(?i=0;?ilen;?i++?)?{
this[?i?]?=?result[?i?];
}
return?this;
}
});
無需思考,我們可以得到 O(n^2) 復雜度的解法。定義一個變量數(shù)組 res 保存結(jié)果,遍歷需要去重的數(shù)組,如果該元素已經(jīng)存在在 res 中了,則說明是重復的元素,如果沒有,則放入 res 中。
[javascript] view plain copy
function unique(a) {
var res = [];
for (var i = 0, len = a.length; i len; i++) {
var item = a[i];
for (var j = 0, jLen = res.length; j jLen; j++) {
if (res[j] === item)
break;
}
if (j === jLen)
res.push(item);
}
return res;
}
var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // = [1, "1", "2"]
代碼非常簡單,那么是否能更簡潔些?如果不考慮瀏覽器兼容,我們可以用 ES5 提供的 Array.prototype.indexOf 方法來簡化代碼。
[javascript] view plain copy
function unique(a) {
var res = [];
for (var i = 0, len = a.length; i len; i++) {
var item = a[i];
(res.indexOf(item) === -1) res.push(item);
}
return res;
}
var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // = [1, "1", "2"]
既然用了 indexOf,那么不妨再加上 filter。
[javascript] view plain copy
function unique(a) {
var res = a.filter(function(item, index, array) {
return array.indexOf(item) === index;
});
return res;
}
var a = [1, 1, '1', '2', 1];
var ans = unique(a);
console.log(ans); // = [1, "1", "2"]
寫一個先:
function?clear(arr)?{
//?1?如何獲取數(shù)組中每一個元素出現(xiàn)的次數(shù)
var?o?=?{};?//?1.1?記錄數(shù)組中元素出現(xiàn)的次數(shù)
for?(var?i?=?0;?i??arr.length;?i++)?{
var?item?=?arr[i];?//?數(shù)組中的每一個元素
//?o[item]?=?1;
//?1.2?判斷o對象是否有當前遍歷到的屬性
if?(o[item])?{
//?如果o[item]?存在,說明次數(shù)不為1
o[item]++;
}?else?{
//?如果o[item]?不存在,說明是第一次出現(xiàn)
o[item]?=?1;
}
}
//?console.log(o);
//?2?生成一個新的數(shù)組,存儲不重復的元素
var?newArray?=?[];
//?2.1?遍歷對象o中的所有屬性
for?(var?key?in?o)?{
//?2.2?判斷o對象中當前屬性的值是否為?1??如果為1?說明不重復直接放到新數(shù)組中
if?(o[key]?===?1)?{
newArray.push(key);
}?else?{
//?o對象中當前屬性?次數(shù)不為1?,說明有重復的,如果有重復的話,只存儲一次
//?判斷當前的newArray數(shù)組中是否已經(jīng)有該元素??
if?(newArray.indexOf(key)?===?-1)?{
newArray.push(key);
}
}
}
return?newArray;
}?
var?array?=?['c',?'a',?'z',?'a',?'x',?'a'];
var?newArray?=?clear(array);
console.log(newArray);
今天小編要跟大家分享的文章是關(guān)于Web前端工程師應該知道的JavaScript使用小技巧。任何一門技術(shù)在實際中都會有一些屬于自己的小技巧。同樣的,在使用JavaScript時也有一些自己的小技巧,只不過很多時候有可能容易被大家忽略。而在互聯(lián)網(wǎng)上,時不時的有很多同行朋友會總結(jié)(或收集)一些這方面的小技巧。
今天在這篇文章中,小編會整理一些大家熟悉或不熟悉的有關(guān)于JavaScript的小技巧,希望能夠?qū)Υ蠹业膶W習和工作有所幫助。
一、數(shù)組
先來看使用數(shù)組中常用的一些小技巧。
01、數(shù)組去重
ES6提供了幾種簡潔的數(shù)組去重的方法,但該方法并不適合處理非基本類型的數(shù)組。對于基本類型的數(shù)組去重,可以使用...new
Set()來過濾掉數(shù)組中重復的值,創(chuàng)建一個只有唯一值的新數(shù)組。
constarray=[1,1,2,3,5,5,1]
constuniqueArray=[...newSet(array)];
console.log(uniqueArray);
Result:(4)[1,2,3,5]
這是ES6中的新特性,在ES6之前,要實現(xiàn)同樣的效果,我們需要使用更多的代碼。該技巧適用于包含基本類型的數(shù)組:undefined、null、boolean、string和number。如果數(shù)組中包含了一個object,function或其他數(shù)組,那就需要使用另一種方法。
除了上面的方法之外,還可以使用Array.from(newSet())來實現(xiàn):
constarray=[1,1,2,3,5,5,1]
Array.from(newSet(array))
Result:(4)[1,2,3,5]
另外,還可以使用Array的.filter及indexOf()來實現(xiàn):
constarray=[1,1,2,3,5,5,1]
array.filter((arr,index)=array.indexOf(arr)===index)
Result:(4)[1,2,3,5]
注意,indexOf()方法將返回數(shù)組中第一個出現(xiàn)的數(shù)組項。這就是為什么我們可以在每次迭代中將indexOf()方法返回的索引與當索索引進行比較,以確定當前項是否重復。
02、確保數(shù)組的長度
在處理網(wǎng)格結(jié)構(gòu)時,如果原始數(shù)據(jù)每行的長度不相等,就需要重新創(chuàng)建該數(shù)據(jù)。為了確保每行的數(shù)據(jù)長度相等,可以使用Array.fill來處理:
letarray=Array(5).fill('');
console.log(array);
Result:(5)["","","","",""]
03、數(shù)組映射
不使用Array.map來映射數(shù)組值的方法。
constarray=[
{
ame:'大漠',
email:'w3cplus@#'
},
{
ame:'Airen',
email:'airen@#'
}
]
constname=Array.from(array,({name})=name)
Result:(2)["大漠","Airen"]
04、數(shù)組截斷
如果你想從數(shù)組末尾刪除值(刪除數(shù)組中的最后一項),有比使用splice()更快的替代方法。
例如,你知道原始數(shù)組的大小,可以重新定義數(shù)組的length屬性的值,就可以實現(xiàn)從數(shù)組末尾刪除值:
letarray=[0,1,2,3,4,5,6,7,8,9]
console.log(array.length)
Result:10
array.length=4
console.log(array)
Result:(4)[0,1,2,3]
這是一個特別簡潔的解決方案。但是,slice()方法運行更快,性能更好:
letarray=[0,1,2,3,4,5,6,7,8,9];
array=array.slice(0,4);
console.log(array);
Result:[0,1,2,3]
05、過濾掉數(shù)組中的falsy值
如果你想過濾數(shù)組中的falsy值,比如0、undefined、null、false,那么可以通過map和filter方法實現(xiàn):
constarray=[0,1,'0','1','大漠','#',undefined,true,false,null,'undefined','null',NaN,'NaN','1'+0]
array.map(item={
returnitem
}).filter(Boolean)
Result:(10)[1,"0","1","大漠","#",true,"undefined","null","NaN","10"]
06、獲取數(shù)組的最后一項
數(shù)組的slice()取值為正值時,從數(shù)組的開始處截取數(shù)組的項,如果取值為負整數(shù)時,可以從數(shù)組末屬開始獲取數(shù)組項。
letarray=[1,2,3,4,5,6,7]
constfirstArrayVal=array.slice(0,1)
Result:[1]
constlastArrayVal=array.slice(-1)
Result:[7]
console.log(array.slice(1))
Result:(6)[2,3,4,5,6,7]
console.log(array.slice(array.length))
Result:[]
正如上面示例所示,使用array.slice(-1)獲取數(shù)組的最后一項,除此之外還可以使用下面的方式來獲取數(shù)組的最后一項:
console.log(array.slice(array.length-1))
Result:[7]
07、過濾并排序字符串列表
你可能有一個很多名字組成的列表,需要過濾掉重復的名字并按字母表將其排序。
在我們的例子里準備用不同版本語言的JavaScript
保留字的列表,但是你能發(fā)現(xiàn),有很多重復的關(guān)鍵字而且它們并沒有按字母表順序排列。所以這是一個完美的字符串列表(數(shù)組)來測試我們的JavaScript小知識。
varkeywords=['do','if','in','for','new','try','var','case','else','enum','null','this','true','void','with','break','catch','class','const','false','super','throw','while','delete','export','import','return','switch','typeof','default','extends','finally','continue','debugger','function','do','if','in','for','int','new','try','var','byte','case','char','else','enum','goto','long','null','this','true','void','with','break','catch','class','const','false','final','float','short','super','throw','while','delete','double','export','import','native','public','return','static','switch','throws','typeof','boolean','default','extends','finally','package','private','abstract','continue','debugger','function','volatile','interface','protected','transient','implements','instanceof','synchronized','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof','do','if','in','for','let','new','try','var','case','else','enum','eval','null','this','true','void','with','await','break','catch','class','const','false','super','throw','while','yield','delete','export','import','public','return','static','switch','typeof','default','extends','finally','package','private','continue','debugger','function','arguments','interface','protected','implements','instanceof'];
因為我們不想改變我們的原始列表,所以我們準備用高階函數(shù)叫做filter,它將基于我們傳遞的回調(diào)方法返回一個新的過濾后的數(shù)組?;卣{(diào)方法將比較當前關(guān)鍵字在原始列表里的索引和新列表中的索引,僅當索引匹配時將當前關(guān)鍵字push到新數(shù)組。
最后我們準備使用sort方法排序過濾后的列表,sort只接受一個比較方法作為參數(shù),并返回按字母表排序后的列表。
在ES6下使用箭頭函數(shù)看起來更簡單:
constfilteredAndSortedKeywords=keywords
.filter((keyword,index)=keywords.lastIndexOf(keyword)===index)
.sort((a,b)=a
這是最后過濾和排序后的JavaScript保留字列表:
console.log(filteredAndSortedKeywords);
Result:['abstract','arguments','await','boolean','break','byte','case','catch','char','class','const','continue','debugger','default','delete','do','double','else','enum','eval','export','extends','false','final','finally','float','for','function','goto','if','implements','import','in','instanceof','int','interface','let','long','native','new','null','package','private','protected','public','return','short','static','super','switch','synchronized','this','throw','throws','transient','true','try','typeof','var','void','volatile','while','with','yield']
08、清空數(shù)組
如果你定義了一個數(shù)組,然后你想清空它。通常,你會這樣做:
letarray=[1,2,3,4];
functionemptyArray(){
array=[];
}
emptyArray();
但是,這有一個效率更高的方法來清空數(shù)組。你可以這樣寫:
letarray=[1,2,3,4];
functionemptyArray(){
array.length=0;
}
emptyArray();
09、拍平多維數(shù)組
使用...運算符,將多維數(shù)組拍平:
10、從數(shù)組中獲取最大值和最小值
可以使用Math.max和Math.min取出數(shù)組中的最大小值和最小值:
constnumbers=[15,80,-9,90,-99]
constmaxInNumbers=Math.max.apply(Math,numbers)
constminInNumbers=Math.min.apply(Math,numbers)
console.log(maxInNumbers)
Result:90
console.log(minInNumbers)
Result:-99
另外還可以使用ES6的...運算符來完成:
constnumbers=[1,2,3,4];
Math.max(...numbers)
Result:4
Math.min(...numbers)
Result:1
二、對象
在操作對象時也有一些小技巧。
01、使用...運算符合并對象或數(shù)組中的對象
同樣使用ES的...運算符可以替代人工操作,合并對象或者合并數(shù)組中的對象。
//合并對象
constobj1={
ame:'大漠',
url:'#'
}
constobj2={
ame:'airen',
age:30
}
constmergingObj={...obj1,...obj2}
Result:{name:"airen",url:"#",age:30}
//合并數(shù)組中的對象
constarray=[
{
ame:'大漠',
email:'w3cplus@#'
},
{
ame:'Airen',
email:'airen@#'
}
]
constresult=array.reduce((accumulator,item)={
return{
...accumulator,
[item.name]:item.email
}
},{})
Result:{大漠:"w3cplus@#",Airen:"airen@#"}
02、有條件的添加對象屬性
不再需要根據(jù)一個條件創(chuàng)建兩個不同的對象,以使它具有特定的屬性。為此,使用...操作符是最簡單的。
constgetUser=(emailIncluded)={
return{
ame:'大漠',
blog:'w3cplus',
...emailIncluded{email:'w3cplus@#'}
}
}
constuser=getUser(true)
console.log(user)
Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}
constuserWithoutEmail=getUser(false)
console.log(userWithoutEmail)
Result:{name:"大漠",blog:"w3cplus"}
03、解構(gòu)原始數(shù)據(jù)
你可以在使用數(shù)據(jù)的時候,把所有數(shù)據(jù)都放在一個對象中。同時想在這個數(shù)據(jù)對象中獲取自己想要的數(shù)據(jù)。
在這里可以使用ES6的Destructuring特性來實現(xiàn)。比如你想把下面這個obj中的數(shù)據(jù)分成兩個部分:
constobj={
ame:'大漠',
blog:'w3cplus',
email:'w3cplus@#',
joined:'2019-06-19',
followers:45
}
letuser={},userDetails={}
({name:user.name,email:user.email,...userDetails}=obj)
{name:"大漠",blog:"w3cplus",email:"w3cplus@#",joined:"2019-06-19",followers:45}
console.log(user)
Result:{name:"大漠",email:"w3cplus@#"}
console.log(userDetails)
Result:{blog:"w3cplus",joined:"2019-06-19",followers:45}
04、動態(tài)更改對象的key
在過去,我們首先必須聲明一個對象,然后在需要動態(tài)屬性名的情況下分配一個屬性。在以前,這是不可能以聲明的方式實現(xiàn)的。不過在ES6中,我們可以實現(xiàn):
constdynamicKey='email'
letobj={
ame:'大漠',
blog:'w3cplus',
[dynamicKey]:'w3cplus@#'
}
console.log(obj)
Result:{name:"大漠",blog:"w3cplus",email:"w3cplus@#"}
05、判斷對象的數(shù)據(jù)類型
使用Object.prototype.toString配合閉包來實現(xiàn)對象數(shù)據(jù)類型的判斷:
constisType=type=target=`[object${type}]`===Object.prototype.toString.call(target)
constisArray=isType('Array')([1,2,3])
console.log(isArray)
Result:true
上面的代碼相當于:
functionisType(type){
returnfunction(target){
return`[object${type}]`===Object.prototype.toString.call(target)
}
}
isType('Array')([1,2,3])
Result:true
或者:
constisType=type=target=`[object${type}]`===Object.prototype.toString.call(target)
constisString=isType('String')
constres=isString(('1'))
console.log(res)
Result:true
06、檢查某對象是否有某屬性
當你需要檢查某屬性是否存在于一個對象,你可能會這樣做:
varobj={
ame:'大漠'
}
if(obj.name){
console.l