总结对象和数组的全部查找方法

187 阅读6分钟

对象的查找方法

构造函数创建一个对象实例,该实例包括自身属性方法,和原型上的方法。

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.say = function() {
        console.log(this.name, this.age);
    }
}
Person.prototype.hello = function() {
    console.log(this.name, 'hello');
}
let xm = new Person('xm', 19);

for ...in :

循环遍历对象的所有属性和方法,包括自身属性方法和原型上的属性方法。并且只遍历对象中可枚举的属性(enumerate为true)。

let propArr = [],propArrValue=[];
for(let i in xm) {
    propArr.push(i);      //获取key
    propArr.push(xm[i]);  //获取value
}
propArr;     //["name", "age", "say", "hello"]
propArrValue: //['xm', 19, ƒ, ƒ]

object.keys:

该方法只能获取对象自身可枚举的属性和方法,不能获取原型上的属性和方法。

let propArr = Object.keys(xm);    //["name", "age", "say"]

object.values:

该方法只能获取对象自身可枚举的属性和方法,不能获取原型上的属性和方法。

let propArr = Object.values(xm);    //['xm', 19, ƒ]

object.entries:

let propArr = Object.entries(xm); //[['name', 'xm'],['age', 19],['say', ƒ]]

object.getOwnPropertyNames:

该方法只能获取对象自身可枚举的属性和方法,不能获取原型上的属性和方法。

let propArr = Object.getOwnPropertyNames(xm);    //["name", "age", "say"]

for...of :

for … of是作为ES6新增的遍历方式,允许遍历一个含有iterator接口的数据结构并且返回各项的值

原生具备 Iterator 接口的数据结构如下:

  • Array
  • Map
  • Set
  • String
  • TypedArray
  • 函数的 arguments 对象
  • NodeList 对象

该方法只能获取对象自身可枚举的属性和方法,不能获取原型上的属性和方法。

//以上例子采用for...of会报错,因为xm不含iterator
//数组含iterator
let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
  console.log(letter);
}
// 结果: a, b, c  (for...of遍历出来的是value,for...in遍历出来的是key)

拓展:如何获取对象原型上的属性和方法?

方法1:for...in

let propProto = [];
for(let i in xm.__proto__) {
    propProto.push(i);
}
console.log(propProto);   //["hello"]

方法2:对象所有属性方法和自身属性方法的数组集合求差

let propAll = [];
for(let i in xm) {
    propAll.push(i);  //["name", "age", "say", "hello"]
}
let propOwn = Object.keys(xm);   //["name", "age", "say"]
let propProto = propAll.filter(function(item) {
    return (propOwn.indexOf(item)<0);
});
console.log(propProto);   //["hello"]

数组的查找方法

forEach

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

不支持break和continue

let sum = 0;

const array1 = [22, 3, 31, 12];

array1.forEach((v, i, a) => {

  sum += v;

});

console.log(sum); // 68

for...in

let arr = [1, 2, 3];
for (let i in arr) {
  console.log(i)  //0 1 2
  console.log(arr[i])  //1 2 3
}

for...of

let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
  console.log(letter);
}
// 结果: a, b, c

find()与findIndex()(es6新增)

find()与findIndex()方法均接受两个参数:一个回调函数,一个可选值用于指定回调函数内部的this。该回调函数可接受三个参数:数组的某个元素,该元素对应的索引位置,以及该数组本身。该回调函数应当在给定的元素满足你定义的条件时返回true,而find()和findIndex()方法均会在回调函数第一次返回true时停止查找。

二者唯一的区别是:find()方法返回匹配的值,而findIndex()返回匹配位置的索引。

let arr = [1, 2, 3, 'arr', 5, 1, 9];
console.log(arr.find((value, keys, arr) => {
  return value > 2;
})); // 3 返回匹配的值

console.log(arr.findIndex((value, keys, arr) => {
  return value > 2;
})); // 2 返回匹配位置的索引

includes(es7新增)

includes() 方法用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

参数有两个,其中第一个是(必填)需要查找的元素值,第二个是(可选)开始查找元素的位置

const array1 = [22, 3, 31, 12, 'arr'];

const includes = array1.includes(31);

console.log(includes); // true

const includes1 = array1.includes(31, 3); // 从索引3开始查找31是否存在

console.log(includes1); // false

需要注意的是:includes使用===运算符来进行值比较,仅有一个例外:NaN被认为与自身相等。

let values = [1, NaN, 2];

console.log(values.indexOf(NaN));//-1

console.log(values.includes(NaN));//true

console.log(NaN===NaN) //false

indexOf

indexOf() 方法可返回数组中某个指定的元素位置。

该方法将从头到尾地检索数组,看它是否含有对应的元素。开始检索的位置在数组 start 处或数组的开头(没有指定 start 参数时)。如果找到一个 item,则返回 item 的第一次出现的位置。开始位置的索引为 0。

如果在数组中没找到指定元素则返回 -1。

参数有两个,其中第一个是(必填)需要查找的元素值,第二个是(可选)开始查找元素的位置

const array1 = [22, 3, 31, 12, 'arr',NaN,undefined];

const index = array1.indexOf(31);

console.log(index); // 2

const index1 = array1.indexOf(31, 3);

console.log(index1); // -1

console.log(array1.indexOf(NaN))  //-1
console.log(array1.indexOf(undefined))  //6

lastIndexOf

lastIndexOf() 方法可返回一个指定的元素在数组中最后出现的位置,在一个数组中的指定位置从后向前搜索。

如果要检索的元素没有出现,则该方法返回 -1。

该方法将从尾到头地检索数组中指定元素 item。开始检索的位置在数组的 start 处或数组的结尾(没有指定 start 参数时)。如果找到一个 item,则返回 item 从尾向前检索第一个次出现在数组的位置。数组的索引开始位置是从 0 开始的。

如果在数组中没找到指定元素则返回 -1。

const array1 = [22, 3, 31, 12, 'arr', 19, 31, 56, 43];

const index1 = array1.lastIndexOf(31);

console.log(index1); // 6

const index2 = array1.lastIndexOf(31, 5);

console.log(index2); // 2

const index3 = array1.lastIndexOf(35);

console.log(index3); // -1

filter

filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

该方法不会改变原数组

const array1 = [22, 3, 31, 12];
const array2 = array1.filter((v, i, a) => {
  if (v > 13) {
    return v;
  }
});
console.log(array1); // [22, 3, 31, 12]
console.log(array2); // [22, 31]

map

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

该方法不会改变原数组

const array1 = [22, 3, 31, 12, 'arr', 19, 31, 56, 43];

const array2 = array1.map((v, i, a) => {

  return v + 1;

});

console.log(array1); // [22, 3, 31, 12, "arr", 19, 31, 56, 43]

console.log(array2); // [23, 4, 32, 13, "arr1", 20, 32, 57, 44]

every

every()方法用于判断数组中每一项是否都满足条件,只有所有项都满足条件,才会返回true。

const array1 = [22, 3, 31, 12];
const isRight1 = array1.every((v, i, a) => {
  return v > 1;
});
const isRight2 = array1.every((v, i, a) => {
  return v > 10;
});
console.log(isRight1); // true
console.log(isRight2); // false

some

some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。

some() 方法会依次执行数组的每个元素:

如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。

const array1 = [22, 3, 31, 12];

const someTrue1 = array1.some((v, i, a) => {

  return v == 11;

});

const someTrue2 = array1.some((v, i, a) => {

  return v == 31;

});

console.log(someTrue1); // false

console.log(someTrue2); // true