为了账号安全,请及时绑定邮箱和手机立即绑定

为什么数字不是带有 typeof 和 instanceof 的 Number 的实例?

为什么数字不是带有 typeof 和 instanceof 的 Number 的实例?

不负相思意 2022-06-16 16:49:13
我需要从数组中获取给定类型的所有元素,就像这样[{ a: 'a' }, 4, /a-z/, 6, [1, 2, 3], i=>i],当我提供类型 Number 作为 ofType(type) 的参数时,它返回 [ ] :Array.prototype.ofType = function (type) {    let newArr = [];     this.forEach(i => i instanceof type ? newArr.push(i) : newArr );    return newArr}在其他情况下,就像[{ a: 'a' }, 4, /a-z/, 6, [1, 2, 3], i=>i].ofType(RegExp)它正常工作一样。
查看完整描述

4 回答

?
HUH函数

TA贡献1836条经验 获得超4个赞

JavaScript 有数字原语和数字对象。数字原语不是instanceof任何东西,因为它不是对象,只有对象是某物的“实例”(“实例”是面向对象编程的艺术术语);所以instanceof对原语没有用。


这就是typeof进来的地方。typeof原始数字的结果是"number"。


由于instanceof期望构造函数作为右手操作数,因此您可以ofType根据它是获取函数还是字符串来使用函数分支,使用instanceof它是否是函数以及typeof是否是字符串。使用你的forEach循环:


Array.prototype.ofType = function (type) {

    let newArr = []; 

    if (typeof type === "string") {

        this.forEach(i => typeof i === type ? newArr.push(i) : newArr );

    } else {

        this.forEach(i => i instanceof type ? newArr.push(i) : newArr );

    }

    return newArr;

};

但我不会forEach为此使用,我会使用filter:


Array.prototype.ofType = function (type) {

    let newArr;

    if (typeof type === "string") {

        newArr = this.filter(i => typeof i === type);

    } else {

        newArr = this.filter(i => i instanceof type);

    }

    return newArr;

};

另外,我强烈建议不要向 中添加可枚举属性Array.prototype,它会破坏错误地for-in在数组上使用循环的代码。改用Object.defineProperty:


Object.defineProperty(Array.prototype, "ofType", {

    value(type) {

        let newArr;

        if (typeof type === "string") {

            newArr = this.filter(i => typeof i === type);

        } else {

            newArr = this.filter(i => i instanceof type);

        }

        return newArr;

    },

    writable: true,

    configurable: true,

    enumerable: false // This is the default, so you could leave it off

});

现场示例:


Object.defineProperty(Array.prototype, "ofType", {

    value(type) {

        let newArr;

        if (typeof type === "string") {

            newArr = this.filter(i => typeof i === type);

        } else {

            newArr = this.filter(i => i instanceof type);

        }

        return newArr;

    },

    writable: true,

    configurable: true,

    enumerable: false // This is the default, so you could leave it off

});


console.log([1, "2", 3, "4"].ofType("number"));


console.log([new Date, "2", new Date, "4"].ofType(Date));


查看完整回答
反对 回复 2022-06-16
?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

Javascript 有对象(即 new Number()、Array、Regexp, ....)和 Primitives('string', 1, true)。instanceof只适用于对象。因此,您的数字是原始数字,无法使用instanceof.


请检查功能toType。toString这里借助 JavaScript 的-method的泛型版本call来获取对应变量的类。它以一种随意的方式解决您的问题。签出以下代码段:


let data = [{ a: 'a' }, 4, /a-z/, 6, [1, 2, 3], i=>i, new Number(5)];


Array.prototype.ofType = function (type) {


  let toType = function(obj) {

    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()

  }


  return this.filter((item) => {

    return toType(item) === type;

  });

}


console.log(data.ofType('number'));

console.log(data.ofType('array'));

console.log(data.ofType('regexp'));


查看完整回答
反对 回复 2022-06-16
?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

只有对象可以instanceof <something>评估为true。每当你有

x instanceof y

如果x不是对象,它将始终评估为false这在此处的规范中有所描述:

如果 Type(O) 不是 Object,则返回 false。

如果您使用数字对象而不仅仅是数字,它将按预期工作并评估为真:


console.log(
   (new Number(5)) instanceof Number 
   );


如果您想检查某些东西是否是特定的原始值,请typeof改用。


查看完整回答
反对 回复 2022-06-16
?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

您可以使用变量构造函数来确定类型(可用于基元和对象等),并对其进行过滤Array。就像是:


Object.defineProperty(Array.prototype, "ofType", {

  value(isType = Number) {

    return this.filter(v => v.constructor === isType);

  },

  writable: true,

  configurable: true,

});


console.log([{a: 'a'}, 4, /a-z/, 6, [1, 2, 3], i => i].ofType());

console.log([{a: 'a'}, 4, /a-z/, 6, [1, 2, 3], i => i].ofType(RegExp));

.as-console-wrapper {

  top: 0;

  max-height: 100% !important;

}


查看完整回答
反对 回复 2022-06-16
  • 4 回答
  • 0 关注
  • 143 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信