【问题标题】:How to extend built-in objects in Javascript, For example Math?如何在 Javascript 中扩展内置对象,例如 Math?
【发布时间】:2018-06-08 11:52:42
【问题描述】:

正在学习调用、应用、绑定三重奏。

然后试试这个:

Math.__proto__.sum = function(arg1){var res=0; for(i in arg1) res+=arg1[i]; return res; };
Math.sum([1,2,3])
//Output: "6function (arg1){var res=0; for(i in arg1) res+=arg1[i]; return res; }"

为什么这个输出包含与 sum 输出相关的函数定义?

我们如何在具有此类实用方法的项目中扩展像 Math 这样的内置对象并完全使用它?

谢谢:)

【问题讨论】:

  • 你可以说Math.sum = function () { /* do stuff */}
  • @mhodges 结果都是一样的。
  • 您需要对数组使用for...of,而不是for...in。如果您使用for...in,它将获取您的属性和所有原型属性,即 1、2、3 和 sum 函数。它在 sum 函数上调用 .toString() 并将其连接到对先前属性求和的答案,这就是您获得输出的原因。
  • @mhodges,嘿,Math.sum 工作了。但我正在寻找为什么它不适用于 Math.__proto__.sum 方法的答案。但是 for .. of 不是 ES6+ 的特性吗?
  • @edam 你不想想要将sum 实现为Math.__proto__ 的成员,首先,因为__proto__ 是一个特定于实现的属性,并且是不可移植,其次是因为 每个 对象都有一个sum() 成员方法是没有意义的。记住Math.__proto__ === Object.prototype,这样你就可以做一些疯狂的事情,比如{}.sum()[].sum()/regexp/.sum()甚至0..sum()

标签: javascript binding bind


【解决方案1】:

这是一个典型的例子,说明你为什么不惹__proto__(除非你绝对知道你在做什么)。将函数附加到Object.prototype 作为可枚举属性会导致它在for...in 循环中被迭代,因为Array 扩展了Object。这会导致函数连接到您的总和并强制转换为字符串。

如果您想为Math 添加功能,在大多数情况下,您可以直接分配给Math

Math.sum = function() {...}

【讨论】:

    【解决方案2】:

    JavaScript 允许您修改原生对象:

    Math.sayHello = function(friend) {
      alert('Hello there ' + friend);
    }
    
    Math.sayHello('buddy');

    当然,当您真正重新定义方法时,这很快就会变得一团糟。

    Math.ceil = function(x) {
      return parseInt(x, 10);
    }
    
    console.log(Math.ceil(4.9));

    【讨论】:

    • Math.prototype 未定义
    • 糟了!更新了答案。
    【解决方案3】:

    最好以与Math.max 相同的方式为Math 实现一个方法,该方法接受参数并返回折叠结果。

    Math.add = (...args) => args.reduce((a, b) => a + b, 0);
    
    console.log(Math.add(1, 2, 3));
    console.log(Math.add(...[7, 8, 9]));

    只有 ES5

    Math.add = function () {
        var i = arguments.length,
            sum = 0;
    
        while (i--) {
            sum += arguments[i];
        }
        return sum;
    };
    
    console.log(Math.add(1, 2, 3));
    console.log(Math.add.apply(null, [7, 8, 9]));

    【讨论】:

    • 嗨@Nina,非常好!你能不使用数组函数表示法来实现它吗?你能解释一下为什么我的不起作用吗? args.reduce 是 ES6+ 特性吗?
    • Array#reduce 是 ES5。您需要哪种实施方式?
    • @edam Yours 不起作用,因为您在数组上使用 for...in 而不是 for...of,不,Array.prototype.reduce 不是 ES6 功能 - 已经存在很长时间了。
    • @NinaScholz 感谢添加 ES5 版本 :)
    猜你喜欢
    • 1970-01-01
    • 2017-01-17
    • 2013-08-03
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-12
    • 1970-01-01
    • 2015-09-01
    相关资源
    最近更新 更多