1、Array.isArray

基本使用

const arr = ["1"];
console.log("isArray:", Array.isArray(arr)); // true

非基本使用:

const arr = ["1"];
const proxy = new Proxy(arr, {});
console.log(proxy); // Proxy {0: '1'}
console.log("isArray:", Array.isArray(proxy)); // true

为什么上面 Array.isArray 判断代理对象是否数组返回 true 呢?
我们可以下面看看打印得到的状态

const arr = ["1"];
const proxy = new Proxy(arr, {});console.log("__proto__:", proxy.__proto__ === Array.prototype); // __proto__: true
console.log("instanceof:", proxy instanceof Array); // instanceof: true
console.log("Proxy toString:", Object.prototype.toString.call(Proxy)); // Proxy toString: [object Function]
console.log("proxy toString:", Object.prototype.toString.call(proxy)); // proxy toString: [object Array]
console.log("Proxy.prototype:", Proxy.prototype); // Proxy.prototype: undefined
console.log("proxy instanceof Proxy:", proxy instanceof Proxy); // 报错

实际Array.isArray判断的是Proxy里面的target属性

如果使用的语法不支持Array.isArray,我们可以手写一个isArray的方法: Object.prototype.toString

Array.isArray = function(obj) {return Object.prototype.toString.call(obj) === "[object Array]";
}
const arr = ["1"];
const proxy = new Proxy(arr, {});
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(proxy)); // true

instanceof 可以正确判断对象的类型,其内部运行原理是:判断其原型链中是否能找到该类型的原型
注意instanceof 只能正确判断引用类型数据,而不能判断基本类型。 instanceof可以用来测试一个对象在其原型链上是否存在一个构造函数的prototype属性。

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false
console.log('str' instanceof String);                // false console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

根据instanceof的原理,可以使用instanceof来手写Array.isArray方法

Array.isArray = function (obj) {if (typeof obj !== "object" || obj === null) {return false;}return obj instanceof Array;
};
const arr = ["1"];
const proxy = new Proxy(arr, {});
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(proxy)); // true

Array.from

有三个参数

  • arrayLike:类数组对象或者可遍历对象(Map、Set)等
  • mapFn:可选参数,在最后生成数组后执行一次map方法后返回
  • thisArg:可选参数,实际是Array.from(obj).map(mapFn, thisArg)
console.log("Array.from1:", Array.from({}));  // Array.from1: []
console.log("Array.from2:", Array.from("")); // Array.from2: []
console.log("Array.from3:", Array.from({ a: 1, length: "10" }));// Array.from3: (10) [undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined]
console.log("Array.from4:", Array.from({ a: 1, length: "ss" })); // Array.from4: []
console.log("Array.from5:", Array.from([NaN, null, undefined, 0])); // Array.from5: (4) [NaN, null, undefined, 0]

根据之前文章《数组高级用法》里面写的类数组特征,可以做如下处理:

// 最大的整数
let maxSafeInteger = Math.pow(2, 32) - 1; // 获取合法有效的整数
let ToInterOrInfinity = function(value) {let number = Number(value);if (isNaN(number)) return 0;if (number === 0 || !isFinite(number)) return number;return (number > 0 ? 1 : -1) *Math.floor(Math.abs(bumber));
}// 获取长度
let ToLength = function (value) {let len = ToInterOrInfinity (value);return Math.min(Math.max(len, 0), maxSafeInteger);
}let isCallable = function(fn) {return typeof fn === 'function' || Object.toString.call(fn) === '[object Function]'
}Array.from = function(arrayLink, mapFn, thisArg) {let C = this;//判断对象是否为空if (arrayLike == null) {throw new TypeError("Array.from requires an array-like object - not null or undefined");}//检查mapFn是否是方法if (typeof mapFn !== "function" && typeof mapFn !== "undefined") {throw new TypeError(mapFn + "is not a function");}let items = Object(arrayLike);//判断 length 为数字,并且在有效范围内。let len = ToLength(items.length);if (len <= 0) return [];let A = isCallable(C) ? Object(new C(len)) : new Array(len);for (let i = 0; i < len; i++) {let value = items[i];if (mapFn) {A[i] = typeof thisArg === "undefined" ? mapFn(value, i) : mapFn.call(thisArg, value, i);} else {A[i] = value;}}return A;
}

Array.entries、Array.prototype.entries

  • 作用:返回一个新的 Array Iterator 对象,该对象包含数组中每个索引的键/值对
const arr = ["a", "b", "c"];const iter = arr.entries();
console.log("iter:", iter); // iter: Array Iterator {}
// next函数访问
console.log("iter.next():", iter.next());
console.log("iter.next():", iter.next());
console.log("iter.next():", iter.next());
console.log("iter.next():", iter.next());
// for of迭代
for (let [k, v] of arr.entries()) {console.log(k, v);
}


done 表示遍历是否结束,value 返回当前遍历的值
自己来实现下这个方法:

Array.prototype.entries = function () {// 转换对象(引用数据类型返回自身)const O = Object(this);let index = 0;const length = O.length;return {next() {if (index < length) {return { value: [index, O[index++]], done: false };}return { value: undefined, done: true };},};
}

上面手写的方法无法使用for of 不能正常执行,我们需要添加Symbol.iterator方法返回next即可实现

Array.prototype.entries = function () {const O = Object(this);let index = 0;const length = O.length;function next() {if (index < length) {return { value: [index, O[index++]], done: false };}return { value: undefined, done: true };}return {next,[Symbol.iterator]() {return {next,};},};
}

数组还有 Array.prototype.keys,Array.prototype.keys,如果我们像上面这样写等于每个方法里面都要实现[Symbol.iterator],我们可以抽离其逻辑,代码如下:

Array.prototype[Symbol.iterator] = function () {const O = Object(this);let index = 0;const length = O.length;function next() {if (index < length) {return { value: O[index++], done: false };}return { value: undefined, done: true };}return {next,};
};Array.prototype.entries = function () {const O = Object(this);const length = O.length;let entries = [];for (let i = 0; i < length; i++) {entries.push([i, O[i]]);}const itr = this[Symbol.iterator].bind(entries)();return {next: itr.next,[Symbol.iterator]() {return itr;},};
};
Array.prototype.keys = function () {const O = Object(this);const length = O.length;let keys = [];for (let i = 0; i < length; i++) {keys.push([i]);}const itr = this[Symbol.iterator].bind(keys)();return {next: itr.next,[Symbol.iterator]() {return itr;},};
};Array.prototype.values = function () {const O = Object(this);const length = O.length;let keys = [];for (let i = 0; i < length; i++) {keys.push([O[i]]);}const itr = this[Symbol.iterator].bind(keys)();return {next: itr.next,[Symbol.iterator]() {return itr;},};
};

Array.prototype.includes

  • 判断数组是否含有某值,可判断NaN
const arr = [1, 2, 3, { a: 1 }, null, undefined, NaN, ""];console.log("includes null:", arr.includes(null)); // includes null: true
console.log("indexOf null:", arr.indexOf(null)); // indexOf null: 4console.log("includes NaN:", arr.includes(NaN)); // includes NaN: true
console.log("indexOf NaN:", arr.indexOf(NaN)); // indexOf NaN: -1

手写该方法

Number.isNaN = function (param) {if (typeof param === "number") {return isNaN(param);}return false;
};
Array.prototype.includes = function (item, fromIndex) {// call, apply调用,严格模式if (this == null) {throw new TypeError("无效的this");}let O = Object(this);let len = O.length >> 0;if (len <= 0) {return false;}const isNAN = Number.isNaN(item);for (let i = 0; i < len; i++) {if (O[i] === item) {return true;} else if (isNAN && Number.isNaN(O[i])) {return true;}}return false;
};

Array.isArray,Array.from, Array.entries,Array.incledes的实现原理,分别手写方法相关推荐

  1. 《前端防坑》- JS基础 - Array.isArray()结果一定准确吗?

    在研究伪数组的时候发现了一个小问题,记录下,就是Array.isArray()判断数组的方法可能与instanceof判断出的结果可能不同. 参考文章:https://www.jianshu.com/ ...

  2. 【javaScript】Object.prototype.toString.call() 、 instanceof 以及 Array.isArray() 区别与优化层面的比较

    1. Object.prototype.toString.call() 每一个继承 Object 的对象都有 toString 方法,如果 toString 方法没有重写的话,会返回 [Object ...

  3. Array.isArray()

    Array.isArray() 作用:用于确定传递的值是否是一个 Array. 描述:如果对象是 Array ,则返回true,否则为false. 语法 Array.isArray(obj) 参数 o ...

  4. JavaScript 实现Array.isArray

    实现效果 实现原生 JavaScript 中的Array.isArray()方法,使用如下: console.log(Array.isArray([])); // true console.log(A ...

  5. Array.isArray 跟 instanceof 的差异

    Array.isArray 如果参数是数组一定返回true,否则一定返回false,在判断对象是否为数组时,采用Array.isArray 更加可靠 instanceof 众所周知,instanceo ...

  6. Array.isArray() instanceof Array

    Array.isArray() 用于确定传递的值是否是一个 Array. H5新增的方法 ie9以上版本支持 Array.isArray([1, 2, 3]); // true Array.isArr ...

  7. JavaScript不清不楚之Array.isArray

    Array.isArray 代码均来自:MDN //利用Object.prototype.toString实现类型判断 if (!Array.isArray) {Array.isArray = fun ...

  8. 数据类型Array.isArray

    const a = []; const b = {}; Array.isArray(a);//true Array.isArray(b);//false

  9. Array.isArray() 判断是不是数组

    var arr = new Array(); if(Array.isArray()){ console.log('yes') } else { conssole.log('no') } 转载于:htt ...

最新文章

  1. Linux:检查当前运行级别的五种方法
  2. CentOS下MySQL的彻底卸载
  3. 选择海外数据中心是否等级越高越好
  4. 信息系统项目管理师优秀论文:项目沟通管理202111
  5. firstchild.data与childNodes[0].nodeValue意思
  6. 2003下安装Comodo pro (通用)
  7. unity 下一帧执行_Unity中的Havok Physics物理引擎
  8. 北京今日起最低工资和养老金标准全部上调
  9. 辞职日记----记录31岁的程序员跳槽心态
  10. 伺服电机常用参数设置_伺服驱动器重要参数的设置方法和技巧
  11. 全国省市区表完整版(自己整理)
  12. mongodb分组统计
  13. html中颜色打字机效果,基于Css3和JQuery实现打字机效果
  14. HARK学习(八)--LoadSourceLocation
  15. 易安卓十六进制数转为十进制数_十六进制转换成十进制的具体算法?
  16. 一看就懂的 安装完ubuntu 18.04后要做的事情和使用教程
  17. wss 协议php,作为ws/wss客户端
  18. HRM人力资源管理平台
  19. 2020年数据中心运维的三大趋势
  20. 硬核体验:裸考深度学习工程师认证考试,是一种怎样的感受?

热门文章

  1. 【Midjourney】Midjourney Prompt 提示词 ② ( 怀旧像素风 | 物体 A 被物体 B 包围 | 折纸艺术风格 )
  2. 薛之谦首唱会座无虚席 新歌全球首唱嗨爆全场
  3. OpenCV实现鱼眼图像径向展开
  4. 如何在Mac上截屏?在Mac上截屏的几种不同方法
  5. 不能错过的2023年最新指纹浏览器盘点
  6. Android service学习笔记
  7. 领歌敏捷协作——一直没有收到邮件的解决办法
  8. 今天在使用docker时出错了,Exited (1) 8 seconds ago
  9. 从头再来安装anaconda3(ubuntu 18.04 TSL)我又来了!!!
  10. React项目经验总结