jquery 数组indexof_js与jquery常用数组方法总结

昨天被问数组方法的时候,问到sort()方法是否会改变原来的数组。本来我猜是不会,也是这么说,马上我又觉得,知识这种东西,不确定的时候直接说不确定或不知道就好,只是凭借着不确定的猜测或者是记忆,害人害己,于是我又回答不知道。结果果然。。。我记错了0.0 还是自己总结测试一下比较靠谱,印象也比较深刻。欢迎大家提出相关意见或建议,提前谢谢哈~

一.原生js方法

1.遍历数组 in(同时也是对象遍历属性的方法)

var a = [1, 2, 3];for (x ina) {

console.log(x);

}

// 0

// 1

// 2

2.合并数组 concat

var a = [1, 2, 3],

b= [4, 5, 6],

c;

c= b.concat(a); //将a加在b后,返回新数组,a和b并没有变。参数数量不限

console.log(b); // [4, 5, 6]

console.log(c); // [4, 5, 6, 1, 2, 3]

3.合并数组的值为字符串 join

var a = [1, 2, 3],

b= a.join('*'); //默认为之间加上 ,

console.log(a); // [1, 2, 3] //a并没有变

console.log(b); // 1*2*3

参数为分隔符,默认为" , "分隔,当参数为' '时表示直接连接,常用于js中拼接html,如自定义弹窗,js生成form表单。

4.数组排序 sort

var a = [6, 2, 3, 'a', 'x', 20],

b= a.sort(); //ASC表顺序,先看首位,因此20排在3前面

console.log(a); // [2, 20, 3, 6, "a", "x"] //a变化了

console.log(b); // [2, 20, 3, 6, "a", "x"]

a.push('k');

console.log(b); // [2, 20, 3, 6, "a", "x", "k"]//a和b指向同一个对象,b相当于a的别名,所以 b 也变了

可以在参数里写排序规则函数, 如全是数字从小到大排序(注意返回值正负)

var a = [3, 2, 6, 20],

b= a.sort(function(x, y) {return x -y;

});

console.log(b);

当不全是数字的时候,会产生奇葩错误(NaN),见下图

由此可知,注意运算符的正确用法还是很重要的。对于NaN,能少操作就少操作,毕竟是唯一一个js中不等于任何值的类型(Not a Number),包括它本身(可以用来判断一个变量是不是NaN,未初始化的变量是无类型的)。

5.数组的模拟栈(FILO) 和队列(FIFO) 方法(均改变原来数组)

var a = [6, 2, 3, 'a', 'x', 20],

b= a.push('ab'), //末尾添加元素,并返回新长度

c = a.pop(), //删除并返回数组的最后一个元素

d = a.unshift('xy'), //开头添加元素,并返回新长度

e = a.shift(); //删除并返回数组的第一个元素

console.log(a);

console.log(b);

console.log(c);

console.log(d);

console.log(e);

可见这类方法添加元素则返回添加后长度, 删除元素则返回被删的那个可怜家伙(同splice)。

6.数组反序 reverse

var a = [6, 2, 3, 'a', 'x', 20],

b= a.reverse(); //返回a的引用

console.log(a); // [20, "x", "a", 3, 2, 6]

console.log(b); // [20, "x", "a", 3, 2, 6]

7.取数组中需要的部分 slice

var a = [6, 2, 3, 'a', 'x', 20],

b= a.slice(0, 2); //下标从0取到2(不包括2),没有第二个参数则默认到末尾。第一个参数为负表示从末尾开始数。第一个参数小于第二个参数则为空。

console.log(a);

console.log(b); // [6, 2]//b是a一部分的副本,a本身不变

8.修改数组 splice (既然是修改数组,肯定数组本身会变的啦)

var a = [1, 2, 3, 4],

b= a.splice(0, 2, 6);

console.log(a); // [6, 3, 4]

console.log(b); // [1, 2]//b为被删掉的数组部分

a.splice(index, num, newItem1, newItem2...):index为开始选择的元素下标,num为接下来要删除元素的个数,newItem为接下来(在删完的地方)要添加的新元素(非必须)。这个方法用途最多,如

删除指定下标(2,也就是第三个)元素,此时不设置需要添加的newItem,而num设为1

var a = [1, 2, 3, 4],

b= a.splice(2, 1);

console.log(a); // [1, 2, 4]

console.log(b); // [3]

在任意位置添加任意多个元素(如在下标2后添加两个元素'7','8'),此时num设为0

var a = [1, 2, 3, 4],

b= a.splice(2, 0, 7, 8);

console.log(a);

console.log(b);//没有删除,b返回[]

根据元素值删除元素(结合jquery)

var a=[1,2,3,4];

a.splice($.inArray(2,a), 1);

console.log(a); // [1, 3, 4]

plus:数组也是特殊的对象(但是拥有自己的方法,一般用下标访问),因此同样也有对象的通用方法toString和valueOf

var a = [1, 2, [3,2], 4],

b= a.toString(); //转化为字符串(不管有多少层)

console.log(a); //a本身不变

console.log(b);

var a = [1, 2, 4],

b= a.valueOf(); //返回原始值(其实还是它本身。。。)

console.log(a); //a本身不变

console.log(b);

小结:综上所述,js数组的原生方法里面

修改自身的有: splice, pop, push, shift, unshift, sort, reverse

不修改自己身的: slice, concat, join

二.Jquery常用js方法

1.遍历

可以对所有的元素进行操作。如果想要满足条件退出,用return false( 绝大部分jquery方法都可以这么退出)。

$.each(arr, callback(key, val));      //可以链式调用,返回arr,为本身

var a = [1, 2, 3, 4];

$.each(a,function(key, val) { //以jQuery对象的方法调用,兼容性好;也可以用$(a)将a转化为jquery对象,然后以$(a).each(function(){})的形式调用,下面的方法同

console.log(a[key] + '下标为' + key + '值为' +val);

});

//对应源码(jquery1.11.0下面同)

// Execute a callback for every element in the matched set.

// (You can seed the arguments with an array of args, but this is

// onlyused internally.

each: function( obj, callback, args ) {varvalue,

i= 0,

length=obj.length,

isArray=isArraylike( obj );if( args ) {if( isArray ) {for ( ; i < length; i++) {

value= callback.apply( obj[ i ], args ); //第三个参数用于扩展obj元素的方法,一般不用

if ( value === false) {break;

}

}

}else{for ( i inobj ) {

value=callback.apply( obj[ i ], args );if ( value === false) {break;

}

}

}//A special, fast, case for the most common use of each

} else{if( isArray ) {for ( ; i < length; i++) {

value=callback.call( obj[ i ], i, obj[ i ] );if ( value === false) {break;

}

}

}else{for ( i inobj ) {

value=callback.call( obj[ i ], i, obj[ i ] );if ( value === false) {break;

}

}

}

}returnobj;

}

2. 筛选

$.grep(arr, callback, invert)

invert为false表示对callback的筛选取反。 默认为true。

var a = [1, 2, 3, 4];

$.grep(a,function(val, key) { //不能链式调用,返回[],所以可以加上return实现链式,返回满足条件的副本

if (a[key] > 2) {

console.log(key);

}returnval;

});

常用做获取两个数组中相同(或不相同)的部分

var a= [1, 2, 3, 4],

b=[1,3,5,7];

$.grep(a,function(val,key){if(b.indexOf(val)>=0){returnval;

}

},false);

//jquery源码

grep: function( elems, callback, invert ) {varcallbackInverse,

matches=[],

i= 0,

length=elems.length,

callbackExpect= !invert;//Go through the array, only saving the items

//that pass the validator function

for ( ; i < length; i++) {

callbackInverse= !callback( elems[ i ], i ); //如果callback没有设置return,那么返回undefined(!undefined还是undefined)if ( callbackInverse !==callbackExpect ) {

matches.push( elems[ i ] ); //只添加满足条件的,内部实现为push方法

}

}returnmatches;

}

3.转换

$.map(arr,callback(key,val))

var a = [1, 2, 3, 4];

$.map(a,function(val, key) { //不能链式调用,返回[],同grep加上return即可放回副本

if (a[key] > 2) {

a[key]=val+1;

}return val; //可以链式调用,返回处理后的数组(也可用于筛选)

});

//arg is for internal usage only

map: function( elems, callback, arg ) {varvalue,

i= 0,

length=elems.length,

isArray=isArraylike( elems ),

ret=[];//Go through the array, translating each of the items to their new values

if( isArray ) {for ( ; i < length; i++) {

value=callback( elems[ i ], i, arg );if ( value != null) {

ret.push( value );

}

}//Go through every key on the object,

} else{for ( i inelems ) {

value=callback( elems[ i ], i, arg ); //如果callback没有返回值,那么value就是undefinedif ( value != null) {

ret.push( value );

}

}

}//Flatten any nested arrays

returnconcat.apply( [], ret );//如果callback没有返回值,那么value就是[]

}

背景标白的区域为与each方法不同的地方,可以简单的理解为返回对象是否是副本(map是副本),另外map是为数组或类数组对象量身定做的,而each可以应用于全部对象。

4.合并

$.merge(arr1,arr2)  arr1后面加上arr2后返回arr1

var a=[1,2,3],

b=[4,5,6];

$.merge(a,b);//可以有多个参数(居然不报错!),但是第三个及以后的没用(test in FF and Chrome)

//jquery源码

merge: function( first, second ) {var len = +second.length,

j= 0,

i=first.length;while ( j

first[ i++ ] = second[ j++];

}//Support: IE<9

//Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)

if ( len !==len ) {while ( second[j] !==undefined ) {

first[ i++ ] = second[ j++];

}

}

first.length=i;returnfirst;

}

源码的第二行有个+,最开始我以为是显式声明非负值,后来看到了arraylike,于是测试了极端情况如下:

varax;

ax.length //报错,type error+ax.length //报错,type errorvar ab={}; //空对象作为类空数组对象

ab.length //undefined+ab.length //NaNvar ab=[];

ab.length //0+ab.length //0var ab=null;

ab.length    //报错,type error+ab.length //报错,type error

忽然觉得然并卵。。。好吧,也许是我计较太多。如果有谁看到有关的解释,麻烦留下言,谢谢~

5.过滤相同元素

$.unique(arr)//过滤Jquery对象数组中重复的元素(内部实现为===)(不同版本不一样,不要用)

var a = [ 1 , 1 , 2 , 3 , 7 , 4 , 5 , 5 , 6 , 6 ];

$.unique(a)

jquery1.11.0运行结果

jquery1.8.3运行结果

好神奇啊,有木有!看一下源码保险~

//jquery1.11.0

jQuery.unique =Sizzle.uniqueSort;

Sizzle.uniqueSort= function( results ) {varelem,

duplicates=[],

j= 0,

i= 0;//Unless we *know* we can detect duplicates, assume their presence

hasDuplicate = !support.detectDuplicates;

sortInput= !support.sortStable && results.slice( 0);

results.sort( sortOrder );if( hasDuplicate ) {while ( (elem = results[i++]) ) {

if ( elem === results[ i ] ) { //用===

j = duplicates.push( i );

}

}while ( j--) {

results.splice( duplicates[ j ],1); //用splice实现

}

}//Clear input after sorting to release objects

//See https://github.com/jquery/sizzle/pull/225

sortInput = null;returnresults;

};

//jquery1.8.3

jQuery.unique =Sizzle.uniqueSort;

Sizzle.uniqueSort= function( results ) {varelem,

duplicates=[],

i= 1,

j= 0;

hasDuplicate=baseHasDuplicate;

results.sort( sortOrder );if( hasDuplicate ) {for ( ; (elem = results[i]); i++ ) {

if ( elem === results[ i - 1 ] ) {

j = duplicates.push( i );

}

}while ( j--) {

results.splice( duplicates[ j ],1);

}

}returnresults;

};

对应红色的字体为新增或者修改的,然而并看不出什么,调试一下进入,会发现问题居然在sortOrder上!坑啊!继续找~~~

//jquery1.11.0//定义时

sortOrder = function(a, b) {if (a ===b) {

hasDuplicate= true;

}return 0;

};//setDocument里面

sortOrder = hasCompare ?

function(a, b) {//Flag for duplicate removal

if (a ===b) {

hasDuplicate= true;return 0;

}//Sort on method existence if only one input has compareDocumentPosition

var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;if(compare) {returncompare;

}//Calculate position if both inputs belong to the same document

compare = (a.ownerDocument || a) === (b.ownerDocument || b) ?a.compareDocumentPosition(b) ://Otherwise we know they are disconnected

1;//Disconnected nodes

if (compare & 1 ||(!support.sortDetached && b.compareDocumentPosition(a) ===compare)) {//Choose the first element that is related to our preferred document

if (a === doc || a.ownerDocument === preferredDoc &&contains(preferredDoc, a)) {return -1;

}if (b === doc || b.ownerDocument === preferredDoc &&contains(preferredDoc, b)) {return 1;

}//Maintain original order

return sortInput ?(indexOf.call(sortInput, a)-indexOf.call(sortInput, b)) :0;

}return compare & 4 ? -1 : 1;

} :function(a, b) {//Exit early if the nodes are identical

if (a ===b) {

hasDuplicate= true;return 0;

}varcur,

i= 0,

aup=a.parentNode,

bup=b.parentNode,

ap=[a],

bp=[b];//Parentless nodes are either documents or disconnected

if (!aup || !bup) {return a === doc ? -1:

b=== doc ? 1:

aup? -1:

bup? 1:

sortInput?(indexOf.call(sortInput, a)-indexOf.call(sortInput, b)) :0;//If the nodes are siblings, we can do a quick check

} else if (aup ===bup) {returnsiblingCheck(a, b);

}//Otherwise we need full lists of their ancestors for comparison

cur =a;while ((cur =cur.parentNode)) {

ap.unshift(cur);

}

cur=b;while ((cur =cur.parentNode)) {

bp.unshift(cur);

}//Walk down the tree looking for a discrepancy

while (ap[i] ===bp[i]) {

i++;

}return i ?

//Do a sibling check if the nodes have a common ancestor

siblingCheck(ap[i], bp[i]) ://Otherwise nodes in our document sort first

ap[i] === preferredDoc ? -1:

bp[i]=== preferredDoc ? 1:0;

};

View Code in jquery1.11.0

//jquery 1.8.3

sortOrder = docElem.compareDocumentPosition ?

function( a, b ) {if ( a ===b ) {

hasDuplicate= true;return 0;

}return ( !a.compareDocumentPosition || !b.compareDocumentPosition ?a.compareDocumentPosition :

a.compareDocumentPosition(b)& 4)? -1 : 1;

} :function( a, b ) {//The nodes are identical, we can exit early

if ( a ===b ) {

hasDuplicate= true;return 0;//Fallback to using sourceIndex (in IE) if it's available on both nodes

} else if ( a.sourceIndex &&b.sourceIndex ) {return a.sourceIndex -b.sourceIndex;

}varal, bl,

ap=[],

bp=[],

aup=a.parentNode,

bup=b.parentNode,

cur=aup;//If the nodes are siblings (or identical) we can do a quick check

if ( aup ===bup ) {returnsiblingCheck( a, b );//If no parents were found then the nodes are disconnected

} else if ( !aup ) {return -1;

}else if ( !bup ) {return 1;

}//Otherwise they're somewhere else in the tree so we need

//to build up a full list of the parentNodes for comparison

while( cur ) {

ap.unshift( cur );

cur=cur.parentNode;

}

cur=bup;while( cur ) {

bp.unshift( cur );

cur=cur.parentNode;

}

al=ap.length;

bl=bp.length;//Start walking down the tree looking for a discrepancy

for ( var i = 0; i < al && i < bl; i++) {if ( ap[i] !==bp[i] ) {returnsiblingCheck( ap[i], bp[i] );

}

}//We ended someplace up the tree so do a sibling check

return i === al ?siblingCheck( a, bp[i],-1) :

siblingCheck( ap[i], b,1);

};

View Code in jquery 1.8.3

很多是不是?有木有觉得瞬间被我坑了?啊哈,其实只要继续调试的时候断点设置好,你就会发现~~~没有比这更坑的了!它们都是循环的!1.8.3里面就在第一个function里面转来转去,手都点酸了也没看到出来,1.11.0整体循环,有参数的个数那么多次。

最后的结论是:还是不要用这个不靠谱的函数了。如果需要类似的功能,用原生js手动写就好。同时说明了关注更新的重要性,不过程序猿也不一定有那么长的时间去关注每一次的更新,那么就一定要准确的了解自己手头的版本,最好是空闲时对用到的功能测试一下,看下源码,网上得来终觉浅啊~

6.判断

$.inArray(val,arr)  判断val是否在arr里面

var a = [1, 2, 3, 4];

$.inArray(2, a); //有的话返回下标,没有的话返回-1

//对应源码

inArray: function(elem, arr, i) {varlen;if(arr) {if(indexOf) {returnindexOf.call(arr, elem, i); //实际实现

}

len=arr.length;

i= i ? i < 0 ? Math.max(0, len + i) : i : 0;for (; i < len; i++) {//Skip accessing in sparse arrays

if (i in arr && arr[i] ===elem) { //一般尽可能用===而杜绝==可能带来的隐式转换returni;

}

}

}return -1;

}

7.元素转数组

$.makeArray()将一个类数组对象转换为真正的数组对象。(所谓"类数组对象"就是一个常规的Object对象,但它和数组对象非常相似:具备length属性,并以0、1、2、3……等数字作为属性名。不过它毕竟不是数组,没有从数组的原型对象上继承下来的内置方法(例如:push()、 sort()等)。)

$.toArray()将所有DOM元素恢复成数组。(其实用选择器取的时候就是很自然的数组的形式)

这两个实际用得太少了就不具体分析了,知道有这玩意就行吧。

The Array.from() method creates a new Array instance from an array-like or iterable

console.log(Array.from('foo'));//expected output: Array ["f", "o", "o"]

console.log(Array.from([1, 2, 3], x => x +x));//expected output: Array [2, 4, 6]

三.补充

1.清空数组

方法1:length设为0 (js身为弱变量类型语言的体现之一,array的length属性可写)(效率比较低)

方法2:直接指向[]的引用 (如闭包销毁指向null一样,垃圾回收会自动回收空间)(效率比较高)

2.兼容性

IE8下

$.inArray 代替 indexOf

$.grep代替Array.prototype.filter

3.注意事项

一般情况下用$.functionName(obj,callback)的形式调用jquery方法的兼容性比较好,比如我曾遇到IE8及以下不能识别$(dom).val().trim()的情况,显示trim is not a function,然而改为$.trim($(dom).val())就没问题。

前面那种情况实际是string调用trim方法(如果加上call或者apply注入trim方法可以过,但是必要嘛?),后面是jquery对象调用trim方法。

最后再啰嗦一句,欢迎大家的意见和建议,帮我纠错,共同进步,谢谢!

附:之前学习权威指南的笔记图

4. Much More(reduce、reduceRight、filter)

MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of

1、The Array.of() method creates a new Array instance with a variable number of arguments, regardless of number or type of the arguments.

Array.of(7); //[7]

Array.of(1, 2, 3); //[1, 2, 3]

Array(7); //[ , , , , , , ]

Array(1, 2, 3); //[1, 2, 3]

2、The copyWithin() method shallow copies part of an array to another location in the same array and returns it, without modifying its size.

[1, 2, 3, 4, 5].copyWithin(-2);//[1, 2, 3, 1, 2]

[1, 2, 3, 4, 5].copyWithin(0, 3);//[4, 5, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(0, 3, 4);//[4, 2, 3, 4, 5]

[1, 2, 3, 4, 5].copyWithin(-2, -3, -1);//[1, 2, 3, 3, 4]

[].copyWithin.call({length:5, 3: 1}, 0, 3);//{0: 1, 3: 1, length: 5}

3、The entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the array.

var array1 = ['a', 'b', 'c'];var iterator1 =array1.entries();

console.log(iterator1.next().value);//expected output: Array [0, "a"]

console.log(iterator1.next().value);//expected output: Array [1, "b"]

4、The every() method tests whether all elements in the array pass the test implemented by the provided function.

functionisBelowThreshold(currentValue) {return currentValue < 40;

}var array1 = [1, 30, 39, 29, 10, 13];

console.log(array1.every(isBelowThreshold));//expected output: true

5、The fill() method fills all the elements of an array from a start index to an end index with a static value.

var array1 = [1, 2, 3, 4];//fill with 0 from position 2 until position 4

console.log(array1.fill(0, 2, 4));//expected output: [1, 2, 0, 0]

//fill with 5 from position 1

console.log(array1.fill(5, 1));//expected output: [1, 5, 5, 5]

console.log(array1.fill(6));//expected output: [6, 6, 6, 6]

6、The filter() method creates a new array with all elements that pass the test implemented by the provided function.

var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result= words.filter(word => word.length > 6);

console.log(result);//expected output: Array ["exuberant", "destruction", "present"]

7、The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

var array1 = [5, 12, 8, 130, 44];var found = array1.find(function(element) {return element > 10;

});

console.log(found);//expected output: 12

8、The includes() method determines whether an array includes a certain element, returning true or false as appropriate.

var array1 = [1, 2, 3];

console.log(array1.includes(2));//expected output: true

var pets = ['cat', 'dog', 'bat'];

console.log(pets.includes('cat'));//expected output: true

console.log(pets.includes('at'));//expected output: false

9、The keys() method returns a new Array Iterator object that contains the keys for each index in the array.

var arr = ['a', 'b', 'c'];var iterator =arr.keys();

console.log(iterator.next());//{ value: 0, done: false }

console.log(iterator.next()); //{ value: 1, done: false }

console.log(iterator.next()); //{ value: 2, done: false }

console.log(iterator.next()); //{ value: undefined, done: true }

10、The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.

const array1 = [1, 2, 3, 4];

const reducer= (accumulator, currentValue) => accumulator +currentValue;//1 + 2 + 3 + 4

console.log(array1.reduce(reducer));//expected output: 10

//5 + 1 + 2 + 3 + 4

console.log(array1.reduce(reducer, 5));//expected output: 15

11、The reduceRight() method applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value.

const array1 = [[0, 1], [2, 3], [4, 5]].reduceRight(

(previousValue, currentValue)=>previousValue.concat(currentValue)

);

console.log(array1);//expected output: Array [4, 5, 2, 3, 0, 1]

12、The some() method tests whether at least one element in the array passes the test implemented by the provided function.

functionisBiggerThan10(element, index, array) {return element > 10;

}

[2, 5, 8, 1, 4].some(isBiggerThan10); //false

[12, 5, 8, 1, 4].some(isBiggerThan10); //true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值