首页 > 解决方案 > 扩展js原型,参数被强制类型

问题描述

我有一个开始的功能是这样的:

Object.prototype.search=function(str){
  var o=this;
  var keys=Object.keys(o);
  var obj={};
  str=str.toLowerCase();
  var regEx=new RegExp(str,"ig");
  ... etc.

注意 - 这只是用于搜索某些数据的快速而肮脏的功能。我确定我想要的可以更有效地实现,但我只是想了解一些东西,等等。

我创建了函数的其余部分,在我第一次在控制台中尝试时,我碰巧给它传递了一个数字。现在数字作为字符串传递,我希望它是一个字符串,当我"555".toLowerCase() 在控制台中运行时,没问题,按预期返回字符串不变。但是,当我尝试执行该函数时,它会引发异常:

uncaught TypeError: str.toLowerCase is not a function
at Number.Object.search

所以我可以看到它正在将我的字符串转换为数字,但我不明白为什么。是因为我正在处理内置对象吗?在我尝试的行上抛出了错误str=str.toLowerCase()。似乎解决方案是将其显式声明为字符串,但我明白我为什么需要这样做。

有任何想法吗?

编辑:这是我的代码 - 我知道这很糟糕,但现在我遇到了其他问题,我只是好奇,因为我不知道发生了什么:

Object.prototype.search=function(str){
  const o=this;
  var keys=Object.keys(o);
  var values=Object.values(o);
  var obj={};
  var regex=new RegExp(str.toLowerCase(),"ig");
  values=values.map((value,index)=>{
    if(value){
      value=value.toString();
      return value.search(regex) !==-1 ? index : false;
    } 
      return false;
   }).filter(e=>!!e);

   values.forEach((e,i)=>{
     var key=keys[i];
     var value=o[key]; 
     obj[key]=value;
  });
  return obj;
  };

编辑: 这是在行动:

var x={"cat":"23","hat":"45"};
x.search("2");

Expected result:  {"cat":"23"};

不:在我包含对值的空值检查后,我不再收到错误,但我也没有得到我期望的结果。换句话说,我得到了一个对象,它被过滤了,但是给定传递的参数,它返回了“错误”的值。

编辑:好的 - 现在已修复。问题出在这一行: var key=keys[i];. 我使用的是键的索引而不是值的索引。所以现在是对的。但我仍然不明白为什么我在 null 检查之前收到错误。如果人们认为我应该关闭它,我会关闭它,但我仍然不明白为什么我会收到错误。

标签: javascripttypes

解决方案


您的功能的更清洁版本:

Object.defineProperty(Object.prototype, 'search', {
  value: function(regex) {
    let found = {};
    for (let k in this) {
      if (this.hasOwnProperty(k) && regex.test(this[k].toString())) found[k] = this[k];
    }
    return found;
  },
  enumerable: false
});

console.log(({ cat: 23, hat: 45 }).search(/2/));
console.log(({ cat: 23, hat: 45 }).search(/.*/));


推荐阅读