1. 程式人生 > 實用技巧 >總結02(陣列方法的重構,將列表轉為陣列,陣列的複製和去重,DOM與BOM)

總結02(陣列方法的重構,將列表轉為陣列,陣列的複製和去重,DOM與BOM)

陣列方法重構

//push
function push(arr){
    for(var i=1;i<arguments.length;i++){
        arr[arr.length]=arguments[i];
    }
    return arr.length;
}
Array.prototype.myPush=function(a,b){
    for(var key in arguments){
        arr[this.length]=arguments[key];
    }
    return this.length;
}
//pop
function pop(arr){
    var elem=arr[arr.length-1];
    if(arr.length>0)arr.length--;
    return elem;
}
Array.prototype.myPop=function(a,b){
    var elem=this[this.length-1];
    this.length-=1;
    return elem;
}
//unshift
function unshift(arr){
    var len=arguments.length-1;
    for(var i=arr.length-1;i>=0;i--){//移位
        arr[i+len]=arr[i];
        arr[i]=null;
    }
    for(var j=1;j<arguments.length;j++){//插入
        arr[j-1]=arguments[j];
    }
    return arr.length;
}
function unshift(arr){
    var arr1=[];
    for(var i=0;i<arr.length;i++){
        arr1[i]=arr[i];
    }
    arr.length=0;
    for(var j=1;j<arguments.length;j++){
        arr[j-1]=arguments[j];
    }
    var len=arr.length;
    for(var k=0;k<arr1.length;k++){
        arr[arr.length]=arr1[k];
    }
    return arr.length;
}
//shift
function shift(arr){
    var elem=arr[0];
    for(var i=1;i<arr.length;i++){
        arr[i-1]=arr[i];
    }
    if(arr.length>0)arr.length--;
    return elem;
}
Array.prototype.myShift=function(){
    var elem=this[0];
    this.splice(0,1);
    return elem;
}
//splice
function splices(arr,delIndex,Num){
    var len=arguments.length-3;
    var delArr=[];
    if(arr.length<=delIndex) return 0;
    if(Num<0) return 0;
    if(~delIndex+1>arr.length) return 0;
    if(delIndex<0){
        delIndex=delIndex+arr.length;
    }
    for(i=0;i<arr.length-delIndex;i++){
        if(i<Num) delArr[i]=arr[delIndex+i];
        arr[delIndex+i]=arr[delIndex+Num+i];
    }
    arr.length-=Num;
    if(arguments[3]){
        arr.length+=len;
        for(i=0;i<len;i++){
            arr[delIndex+i]=arguments[i+3];
        }
        for(i=0;i<len;i++){
            arr[delIndex+i]=arguments[i+3];
        }
    }
}
//slice
function slice(arr,slice,end){
    if(start===undefined)start=0;
    if(end===undefined)end=arr.length;
    start=Number(start);
    end=Number(end);
    if(isNaN(start)start=0;
    if(isNaN(end)end=arr.length;;
    if(start<0)start=arr.length+start;
    if(end<0)end=arr.length+end;
    var arr1=[];
    for(var i=start;i<end;i++){
        arr1[i-start]=arr[i];
    }
    return arr1;
}
//concat
function concat(arr){
    var arr1=[];
    for(var i=0;i<arr.length;i++){
        arr1[i]=arr[i];
    }
    if(arguments.length===1) return arr1;
    for(var j=1;j<arguments.length;j++){
        if(arguments[j]!==null && arguments[j].constructor===Array){
        for(var k=0;k<arguments[j].length;k++){
            arr1[arr1.length]=arguments[j][k];
        }
        }else{
            arr1[arr1.length]=arguments[j];
        }
    }
    return arr1;
}
//join
function join(arr,separator){
    if(separator===undefined) separator=",";
    separator=String(separator);
    var str="";
    for(var i=0;i<arr.length;i++){
        if(i!==arr.length-1) str+=arr[i]+separator;
        else str+=arr[i];
    }
    return str;
}
//sort
function sort(arr){
    var len=arr.length-1;
    while(len>0){
        for(var i=0;i<arr.length-1;i++){
            if(arr[i]>arr[i+1]){
                var temp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=temp;
            }
        }
        len--;
    }
}
​
function sort(arr,fn){
    var len=arr.length-1;
    while(len>0){
        for(var i=0;i<arr.length-1;i++){
            // if(arr[i]>arr[i+1])
            // if(arr[i]-arr[i+1]>0)
            // if(a-b)
            if(fn(arr[i],arr[i+1])>0){
                var temp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=temp;
            }
        }
        len--;
    }
}
var arr = [3, 7, 2, 9, 1, 0, 6, 5, 4, 4, 12, 11];
sort(arr,function(a,b){
    return b-a;
});
console.log(arr);
​
//reverse
function reverse(arr){
    var len=parseInt(arr.length/2);
    for(var i=0;i<len;i++){
        var temp=arr[i];
        arr[i]=arr[arr.length-i-1];
        arr[arr.length-i-1]=temp;
    }
    return arr;
} 
function reverse(arr){
    var arr1=[];
    for(var i=0;i<arr.length;i++){
        if(i in arr){
            arr1[i]=arr[i];
        }
    }
    arr.length=0;
    for(var j=arr1.length-1;j>=0;j--){
        if(j in arr1){
            arr[arr1.length-j-1]=arr1[j];
        }
    }
    return arr;
}
//indexOf
function indexOf(arr,search,index){
    if(index===undefined) index=0;
    for(var i=index;i<arr.length;i++){
        if(arr[i]===search) return i;
    }
    return -1;
}
//forEach
function forEach(arr,fn){
    for(var i=0;i<arr.length;i++){
        if(i in arr) fn(arr[i],i,arr);
    }
}
//map
function map(arr,fn){
    var arr1=[];
    for(var i=0;i<arr.length;i++){
        if(i in arr) arr1[i]=fn(arr[i],i,arr);
    }
    return arr1;
}
//some
function some(arr,fn){
    for(var i=0;i<arr.length;i++){
        if(i in arr && fn(arr[i],i,arr)) return true; 
    }
    return false;
}
//every
function every(arr,fn){
    for(var i=0;i<arr.length;i++){
        if(i in arr && !fn(arr[i],i,arr)) return false; 
    }
    return true;
}
//filter
function filter(arr,fn){
    var arr1=[];
    if(arr.length===0) return arr1;
    for(var i=0;i<arr.length;i++){
        if(fn(arr[i],i,arr)) arr1.push(arr[i]);      
    }
    return arr1;
}
//reduce
function reduce(arr,fn,initValue){
    var index=0;
    if(initValue===undefined){
        initValue=arr[0];
        index=1;
    }
    for(;index<arr.length;index++){
        initValue=fn(initValue,arr[index],index,arr);
    }
    return initValue;
}

將列表強轉為陣列

var divs=document.getElementsByTagName("div");//強轉為陣列
var arr=Array.from(divs);//ES6,把列表強轉為陣列,老瀏覽器不支援
​
var arr=Array.prototype.slice.call(divs);
var arr=[].slice.call(divs);//這兩種屬於同一種方法
​
var arr=Array.prototype.concat.apply([],divs);
var arr=[].concat.apply([],divs);

陣列複製的方法

//陣列複製的方法,沒有引用關係
concat arr.concat()
slice arr.slice()/arr.slice(0)
​
splice(0) arr.splice(0)//轉移到另一個新陣列
splice() arr.splice()//返回空陣列
​
//indexof
var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
var arr1=[];
for(var i=0;i<arr.length;i++){
    if(arr1.indexOf(arr[i])<0) arr1.push(arr[i]);
}
console.log(arr1); 
​
//遍歷,不推薦使用
var arr1=[];
var arr=[{'id':1,'price':'5.0'},{'id':2,'price':'10.00'},{'id':3,'price':' 20.00 '}];
for(var i in arr){
    var v=arr[i];
    var obj={};
    obj.id=v.id;
    obj.price=v.price;
    arr1.push(obj);
}
​
//map方法
arr = [1, 2, 3];
double = (x) => x ;
arr1=arr.map(double);
​
//擴充套件運算子
numbers = [1, 2, 3];
numbersCopy = [...numbers];
//這個方法不能有效的拷貝多維陣列。陣列/物件值的拷貝是通過引用而不是值複製。
// numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
// 只修改了我們希望修改的,原陣列不受影響
// nestedNumbers = [[1], [2]];
numbersCopy = [...nestedNumbers];
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
// 由於公用引用,所以兩個陣列都被修改了,這是我們不希望的
​
//filter
var arr= [1, 2, 3];
arr1= arr.filter(() => true);
​
//reduce
numbers = [1, 2, 3];
numbersCopy = numbers.reduce((newArray, element) => {
 newArray.push(element);
 return newArray;
}, []);
​
//Array.from
numbers = [1, 2, 3];
numbersCopy = Array.from(numbers)

陣列去重

//splice
var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
var len=arr.length;
for(var i=0;i<len;){
    if(arr[i]===3) arr.splice(i,1);
    else i++;//這樣才可以刪除兩個連續重複的元素
}
console.log(arr); 
for(var i=0;i<arr.length;i++){
    arr.pop();
}
console.log(arr);
​
//外層迴圈
var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
var arr1=[];
for(var i=0;i<arr.length;i++){
    var bool=false;
    for(var j=0;j<arr1.length;j++){
        if(arr[i]===arr1[j]){
            bool=true;
            break;
        }
    }
    if(!bool) arr1.push(arr[i]);
}//複製不重複的數給一個新陣列
arr.length=0;
for(var k=0;k<arr1.length;k++){
    arr[k]=arr1[k];
}//把這個新陣列給原陣列
arr1.length=0;
arr1=null;//把新陣列刪除
console.log(arr); 
​
//indexOf
var arr=[1,3,3,6,8,2,3,5,6,3,7,9,8,3,6,7,3,8,9];
var arr1=[];
for(var i=0;i<arr.length;i++){
    if(arr1.indexOf(arr[i])<0) arr1.push(arr[i]);
}
console.log(arr1); 
//sort
function unique(arr){
    if(!Array.isArray(arr)){
        console.log('type error');
        return;
    }
    arr=arr.sort();
    var array=[arr[0]];
    for(var i=1;i<arr,length;i++){
        if(arr[i]!==arr[i-1]){
            array.push(arr[i])
        }
    }
    return array;
}
​
//利用物件的屬性不能相同
function unique(arr){
    if(!Array.isArray(arr)){
        console.log('type error');
        return;
    }
    var array=[];
    var obj={};
    for(var i=0;i<arr.length;i++){
        if(!obj[arr[i]]){
            array.push(arr[i]);
            obj[arr[i]]=1
        }else{
            obj[arr[i]]=1
        }
    }
    return array;
}
​
//filter
function unique(arr){
    return arr.filter(function(item,index,arr){
        return arr.indexOf(item,0)===index;
    })
}
​
//遞迴去重
function unique(arr){
    var array=arr;
    var len=array.length;
    array.sort(function(a,b){
        return a-b;
    })
    function loop(index){
        if(index>=1){
            if(array[index]===array[index-1]){
                array.splice(index,1);
            }
            loop(index-1);
        }
    }
    loop(len-1);
    return array;
}
通過call方法,這個方法也可以用於字串或類似陣列的物件。
Array.prototype.join.call('hello', '-')
// "h-e-l-l-o"
​
var obj = { 0: 'a', 1: 'b', length: 2 };
Array.prototype.join.call(obj, '-')
// 'a-b'
[].concat({a: 1}, {b: 2})
// [{ a: 1 }, { b: 2 }]
​
[2].concat({a: 1})
// [2, {a: 1}]
如果陣列成員包括物件,concat方法返回當前陣列的一個淺拷貝。所謂“淺拷貝”,指的是新陣列拷貝的是物件的引用。
Array.prototype.slice.call({ 0: 'a', 1: 'b', length: 2 })
// ['a', 'b']
Array.prototype.slice.call(document.querySelectorAll("div"));
Array.prototype.slice.call(arguments);
// bad
[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a > b)
​
// good
[1, 4, 2, 6, 0, 6, 2, 6].sort((a, b) => a - b)
上面程式碼中,前一種排序演算法返回的是布林值,這是不推薦使用的。後一種是數值,才是更好的寫法。
map方法還可以接受第二個引數,用來繫結回撥函式內部的this變數(詳見《this 變數》一章)。
var arr = ['a', 'b', 'c'];
​
[1, 2].map(function (e) {
  return this[e];
}, arr)
// ['b', 'c']
上面程式碼通過map方法的第二個引數,將回調函式內部的this物件,指向arr陣列。
var f = function (n) { return 'a' };
​
[1, undefined, 2].map(f) // ["a", "a", "a"]
[1, null, 2].map(f) // ["a", "a", "a"]
[1, , 2].map(f) // ["a", , "a"]
上面程式碼中,map方法不會跳過undefined和null,但是會跳過空位。

DOM&BOM

瀏覽器視窗尺寸

//實用的 JavaScript 方案(涵蓋所有瀏覽器):
var w=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
var h=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;

判斷某元素是div

console.log(document.body.firstChild.nodeName==="DIV");
console.log(document.body.firstChild.constructor===HTMLDivElement);

NodeList&HTMLCollection

// NodeList
var div=document.querySelectorAll(所有選擇器)
var list=document.getElementsByName("sex");
//通過name屬性獲取節點列表,只能通過document獲取,NodeList
//nodeList是有forEach方法遍歷  
var list=document.getElementsByName("sex");
    list.forEach(function(item){
    console.log(item);
})
​
//HTMLCollection
var list=document.getElementsByTagName("div");
//通過標籤名獲取標籤列表,只能通過document獲取,HTMLCollection
var list=document.getElementsByClassName("div1") 
//通過Class名獲取標籤列表,任何標籤都可以獲取其子項中Class列表,HTMLCollection
console.log(list)
//用Array.from轉成陣列

所有節點可使用&僅為document使用

//僅document
var list=document.getElementsByName("sex");//多用於表單
var div0=document.getElementById("div0");
//所有節點
var list=document.getElementsByTagName("div");
var list=document.getElementsByClassName("div1");
var div=父容器.querySelector();
var div=document.querySelectorAll();

物件屬性&標簽屬性

// DOM 物件屬性
// DOM的物件屬性,分為自定義型和原DOM物件屬性
// DOM的物件原屬性與DOM物件的標籤屬性部分對應,部分有差別
div.className="div1";//就是設值class標籤屬性
​
// DOM 標籤屬性
// 設定標籤的屬性和值,值和屬性都必須是字元型別
// DOM的標籤屬性命名,不能使用大小寫區分不適用下劃線區分
// 屬性名必須全小寫字母,並且使用-區分每個單詞
div.setAttribute("shop-data","10");
// 獲取標籤屬性
console.log(div.getAttribute("shop-data"));
console.log(div.getAttribute("class"));
// 刪除標籤屬性
div.removeAttribute("shop-data");
​
//衝突時,物件屬性優先
input.checked=true;