首页 > 解决方案 > JS值可以是数组和函数吗?Array.isArray(v) + typeof v === '函数'

问题描述

JS值可以是数组和函数吗?

const isArrayAndFunc = v => {
  return Array.isArray(v) && typeof v === 'function';
}

可以isArrayAndFunc为 JS 中的值返回 true 吗?

我不认为它是,但只是检查。

标签: javascriptnode.js

解决方案


可能被认为是作弊,但可以覆盖Array.isArray以实现您自己的逻辑:

Array.isArray = () => true;
const isArrayAndFunc = v => {
  return Array.isArray(v) && typeof v === 'function';
};

console.log(isArrayAndFunc(() => 'foo'));

在内部,Array.isArray在 ES5 中,检查

如果 arg 的 [[Class]] 内部属性的值为“Array”,则返回 true。

这是一个内部属性,不能修改:

该规范没有定义允许程序修改对象的[[Class]]或 [[Prototype]] 内部属性或将 [[Extensible]] 的值从 false 更改为 true 的ECMAScript 语言运算符或内置函数。修改 [[Class]]、[[Prototype]] 或 [[Extensible]] 的实现特定扩展不得违反前一段中定义的不变量。

ES6中:

  1. 如果参数是 Array 外来对象,则返回 true。
  2. 如果参数是代理外来对象,则

    一个。如果参数的 [[ProxyHandler]] 内部槽的值为 null,则抛出 TypeError 异常。

    湾。令 target 为 [[ProxyTarget]] 内部参数槽的值。

    C。返回 IsArray(目标)。

对于 2.,似乎没有任何方法可以将任何对象(或函数)转换为“数组外来对象”。setPrototypeOf可用于设置函数的内部原型,但它实际上仍不会是“数组外来对象”。

'use strict';
const fn = () => 'foo';
Object.setPrototypeOf(fn, Array);

const isArrayAndFunc = v => {
  return Array.isArray(v) && typeof v === 'function';
};
console.log(isArrayAndFunc(fn));

对于 3,如果正在检查的对象是 Proxy,那么typeof它将是一个object,而不是一个函数。

因此,除非您覆盖Array.isArray(或覆盖/阴影Array本身),否则我认为isArrayAndFunc永远不会返回true.


推荐阅读