【问题标题】:Alter the Math functions in Javascript更改 Javascript 中的数学函数
【发布时间】:2015-02-27 04:33:06
【问题描述】:

我正在尝试“更改”来自 Math 对象的 sin cos 和 tan 函数,以便它可以接受识别它是度数“d”还是弧度。我对如何做到这一点有一个想法,但我不知道在不改变我的主要功能的情况下做到这一点

(function() {
   var angle;
         
   while (angle = parseFloat(readline())) {
      print(Math.sin(angle, "d").toPrecision(5));  // degrees
      print(Math.sin(angle).toPrecision(5));       // radians
      print(Math.cos(angle, "d").toPrecision(5));
      print(Math.cos(angle).toPrecision(5));
      print(Math.tan(angle, "d").toPrecision(5));
      print(Math.tan(angle).toPrecision(5));
   }
})();
alter 如何起作用,以便他们可以接受我尝试使用 Object.create 和 JSON.parse(JSON.stringify(Math)); 之类的“d”参数但它不起作用我需要知道如何深度复制数学

【问题讨论】:

  • 为什么不定义一个自定义函数来区分度数/弧度输入,并使其从其中调用 sin/cos/tan 函数?
  • Like function toRad() { ...//I call my math functions} 但这对 main 有什么帮助我无法更改 main 函数
  • 我的意思是,定义一个function YourOwnSinFunc(angle, isRadian) { if (isRadian) { Math.sin(angle); }else { //do computing Math.sin(angleinradians); } 并从您的代码中直接调用它而不是 Math.sin!
  • 如果不能更改调用代码,它将如何使用这个新功能?
  • 人为的限制,比如“不能改变主功能”,尤其是当你需要来改变它以使用这个功能(正如@Ingo 指出的那样)散发着课堂作业的味道。在这种情况下,您可能应该自己解决问题。这并不是说我们在行业中还没有 足够的懒惰编码员 :-)

标签: javascript


【解决方案1】:

您可以使用继承自 Math 的对象覆盖 Math(在闭包中):

(function(globalMath) {

    // Overriding Math:
    var Math = Object.create(globalMath);

    // Enhancing trigonometric methods:
    var trig = ['sin', 'cos', 'tan'];
    for(var i=0; i<3; ++i)
        Math[trig[i]] = (function(trigFunc){
            return function(angle, d) {
                if(d==="d") angle *= Math.PI / 180;
                return trigFunc(angle);
            };
        })(globalMath[trig[i]]);

    // Now you can use the enhanced methods:
    Math.sin(Math.PI/6); // 0.5
    Math.sin(30, 'd');   // 0.5

    // You can also use original methods:
    globalMath.sin(Math.PI/6);      // 0.5
    globalMath.sin(Math.PI/6, 'd'); // 0.5 ('d' is ignored)

    // Math is a shortcut of globalMath for other methods:
    Math.max(1,2); // 2

})(Math);

【讨论】:

    【解决方案2】:

    JavaScript 中的一切都是对象,因此您可以重写原生的 Math 函数。但正如其他评论员所说,不建议这样做。

    创建自己的内部转换为度数的函数更简单,如下所示:

    function sinDegrees(angle) {
        return Math.sin(angle * (Math.PI / 180));
    }
    

    如果你愿意,它甚至可以是 Math 对象的一部分:

    Math.sinDegrees = sinDegrees;
    

    如果你还想像这样修改Math.sin函数,那么你可以这样做:

    Math._sin = Math.sin; // save a ref. to the old sin
    Math.sin = function sin(angle, type) {
        if (type == 'd')
            return Math._sin(angle * (Math.PI / 180));
        else
            return Math._sin(angle);
    }
    

    【讨论】:

    • 我正要讨论重新定义函数。但是它可能会破坏其他使用内置方法的代码。因此,OP 应注意不要破坏现有功能。注意:您的样本仍然允许调用原罪成功,但我只是说任何遵循这种方法的人也应该注意它!
    • 好的,所以 _sin 指向 Math.sin 但是我 Math.sin 指向一个新函数。我试图这样做,但使用 Math.sin = function();它觉得这是为什么?它正在递归调用。
    • @user2822413:使用我发布的代码正常工作,这是demo
    • @user2822413:因为math.sin 末尾的括号是在调用函数,而不是按原样获取函数对象。
    • 我正在尝试 var _sin = Math.sin;然后调用 Math.sin = function(degree, angle) {... this._sin..} 为什么不起作用?
    【解决方案3】:

    这里更好的解决方案是有一个 toRad 函数。它看起来与您的目标代码非常相似,但没有破坏基本的良好实践(不要修改您未创建的对象)。

    function toRad(angle){
        return angle * (Math.PI / 180);
    }
    
    print(Math.sin(toRad(angle)).toPrecision(5));  // degrees
    print(Math.sin(angle).toPrecision(5));       // radians
    print(Math.cos(toRad(angle)).toPrecision(5));
    print(Math.cos(angle).toPrecision(5));
    print(Math.tan(toRad(angle)).toPrecision(5));
    print(Math.tan(angle).toPrecision(5));
    

    这也使您免于定义每个函数的自定义版本。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多