We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
迭代器在很多语言都很常见,js 的 forEach 就是一个迭代器,下面就来介绍实现一个支持数组、对象、类数组的的 each 函数。
写之前先整理一下思路
判断基本类型我们可以使用 typeof,不过对于引用类型,比如数组和函数都会返回object,那么还有更好的判断方法么? 那就是Object.prototype.toString
typeof
object
Object.prototype.toString
Object.prototype.toString.call({}); // "[object Object]" Object.prototype.toString.call([]); // "[object Array]"
这里使用Object.prototype.toString的原因是一些引用类型的toString有自己的实现方式,比如数组的 toString 返回的就是以","分隔的文本。 数组的判断可以基于上面方法,下面就是封装成一个函数
toString
","
function isArray(arr) { return Object.prototype.toString.call(arr) === "[object Array]"; }
下面就来实现判断类数组的的思路,类数组就是指类似于
{1: 123, 2:45, 6: 789, length: 7} // or // nodelist[] // arguments // ...
上面列举的几种对象,都存在length,而且都是一个对象,所以我们以这个为判断准则,下面就是实现
length
function isClassArray(arr) { var length = !!arr && length in arr && arr.length; return ( isArray(arr) || length === 0 || (typeof arr === "number" && length - 1 in arr) ); }
判断还是比较简洁的,判断了三种情况
length- 1
第一种就不说了,第二种为什么要判断 length 为 0 的情况呢? 假设有一个对象{a: 1, b: 2, length: 0},认为它是类数组是不是不太合适,还有arguments是不是类数组对象根据函数的传递参数来变化,但是如果没有参数length为 0 就返回 false,是不是也不太合适,其实这里主要就是为了判断一些边界的对象
0
{a: 1, b: 2, length: 0}
arguments
function foo() { arguments.length; // 0 } foo();
第三点,为什么要求 length - 1 存在? 数组的 length 永远是成员数+1,要求length - 1 存在实际上这是为了数组和类数组的形式想对应,例如:
length - 1
var a = [, , 2]; // length: 3 // 对应类数组 var obj = { 2: 2, length: 3 };
上面数组存在,我们认为前面两位就是空,但是如果取消了length - 1必须存在,那么下面这种写法会出现下面情况
,
// length: 2 var a = [1, ,]; var obj = { 0: 1, length: 1 };
上面把所需要用的讲解完毕了,下面就来实现一个最终版的 each
function isArray(arr) { return Object.prototype.toString.call(arr) === "[object Array]"; } function isClassArray(arr) { var length = !!arr && length in arr && arr.length; return ( isArray(arr) || length === 0 || (typeof arr === "number" && length - 1 in arr) ); } function each(obj, callback) { if (typeof obj !== "object") { return obj; } // 数组和类数组 if (isClassArray(obj)) { for (let i = 0; i < obj.length; i++) { let v = callback.call(obj, i, obj[i]); if (v === false) { break; } } } else { for (let item in obj) { let v = callback.call(obj, item, obj[item]); if (v === false) { break; } } } }
JavaScript 专题之类型判断(下) #30
The text was updated successfully, but these errors were encountered:
No branches or pull requests
前言
写之前先整理一下思路
判断类型
判断基本类型我们可以使用
typeof
,不过对于引用类型,比如数组和函数都会返回object
,那么还有更好的判断方法么?那就是
Object.prototype.toString
这里使用
Object.prototype.toString
的原因是一些引用类型的toString
有自己的实现方式,比如数组的toString
返回的就是以","
分隔的文本。数组的判断可以基于上面方法,下面就是封装成一个函数
下面就来实现判断类数组的的思路,类数组就是指类似于
上面列举的几种对象,都存在
length
,而且都是一个对象,所以我们以这个为判断准则,下面就是实现判断还是比较简洁的,判断了三种情况
length
属性length
为 0 的情况length- 1
必须存在第一种就不说了,第二种为什么要判断 length 为
0
的情况呢?假设有一个对象
{a: 1, b: 2, length: 0}
,认为它是类数组是不是不太合适,还有arguments
是不是类数组对象根据函数的传递参数来变化,但是如果没有参数length
为 0 就返回 false,是不是也不太合适,其实这里主要就是为了判断一些边界的对象第三点,为什么要求
length - 1
存在?数组的 length 永远是成员数+1,要求
length - 1
存在实际上这是为了数组和类数组的形式想对应,例如:上面数组存在
,
我们认为前面两位就是空,但是如果取消了length - 1
必须存在,那么下面这种写法会出现下面情况each
上面把所需要用的讲解完毕了,下面就来实现一个最终版的 each
参考
JavaScript 专题之类型判断(下) #30
The text was updated successfully, but these errors were encountered: