數組方法重構
//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;