【问题标题】:Comparing 2 functions in JavaScript比较 JavaScript 中的 2 个函数
【发布时间】:2014-05-24 12:37:48
【问题描述】:

在比较 Javascript 中的函数时,我认为它会比较定义函数的内存以交叉检查给定的 2 个函数是否相等。
因此,试图通过从同一对象的 2 个不同实例访问成员函数来比较成员函数,如下所示:

function testFn(name) {
    var name = name;
    var self = this;
    self.compareFn = function() {
        console.info(name);
    }    
}

var fn1 = new testFn('fn1');
var fn2 = new testFn('fn2');
console.info(fn1.compareFn == fn2.compareFn);  //Returns false

已经用一个成员函数(“compareFn”)定义了一个对象 testFn 并创建了它的 2 个实例(fn1,fn2),但是在比较“fn1.compareFn == fn2.compareFn”时,它失败了。

请记住,成员函数在多个实例之间共享,并且只有局部变量会被单独分配。
请说明此比较失败的原因。

【问题讨论】:

    标签: javascript function


    【解决方案1】:

    该方法实际上是为每个实例创建的。您想在对象的原型上声明它。见下文。

    var testFn = function(name) {
        this.name = name;
    }
    
    testFn.prototype.compareFn = function() {
       console.info(this.name);
    }
    
    var fn1 = new testFn('fn1');
    var fn2 = new testFn('fn2');
    console.info(fn1.compareFn == fn2.compareFn);  //Returns true
    

    【讨论】:

    • 我觉得你比我快几秒 :)
    【解决方案2】:

    如果您希望函数在多个实例之间共享,请这样做:

    function testFn(name) {
        var self = this;
    }
    
    testFn.prototype.compareFn = function() {
      console.log(name);
    };    
    
    var fn1 = new testFn('fn1');
    var fn2 = new testFn('fn2');
    console.log(fn1.compareFn == fn2.compareFn); 
    

    DEMO

    【讨论】:

      【解决方案3】:

      这会失败,因为每次您执行new testFn 都会生成一个新的compareFn;您没有指向构造函数之外的引用或从原型继承。

      您不能使用共享函数从 构造函数 内部访问 variable,因为它无权访问该闭包。如果您想实现共享功能,您还需要将这些值移动到可引用的空间中,即

      function testFn(name) {
          var vars = {}; // using object because javascript passes refs for objects
          this.vars = vars; // make `this.vars` point to `vars`
          vars.name = name; // set whatever on your object
      }
      testFn.prototype.compareFn = function () {
          console.info(this.vars.name); // can access `vars` through ref of `this.vars`
      };
      

      现在

      var a = new testFn('foo'), b = new testFn('bar');
      a.compareFn === b.compareFn; // true;
      a.compareFn(); // logs "foo"
      

      【讨论】:

        【解决方案4】:

        每次调用函数testFn时,它都会创建一个新变量并为其分配一个函数...

        所以是的,它们是相同的功能,但它们不是同一个东西。

        您可以使用其他几种模式来获得您想要的结果。在这种情况下,您需要使用原型模式:

        // Constructors should start with an upper case letter
        function TestFn(name) {
          this.name = name;
        }
        
        TestFn.prototype.testFn = function() {
          console.info(this.name);
        }    
        
        
        var fn1 = new TestFn('fn1');
        var fn2 = new TestFn('fn2');
        console.info(fn1.compareFn == fn2.compareFn);  // Returns true
        

        【讨论】:

          【解决方案5】:
          function testFn(name) {
              this.name = name;
          }
          
          testFn.prototype.compareFn = function() {
              console.info(name);
          }
          
          var fn1 = new testFn('fn1');
          var fn2 = new testFn('fn2');
          console.info(fn1.compareFn == fn2.compareFn);  //Returns TRUE
          

          每次调用构造函数时都在重新定义函数,因此方法不相等。通过将它们分配给原型,它是相同的方法。

          如果您有兴趣保持name(或其他变量或函数的私有),请查看this SO answer

          【讨论】:

            【解决方案6】:

            我认为它以false 出现的原因是,至少在这里,不是测试“源代码”结果的相等性,而是测试它们都引用的内存位置。这是因为它无法以任何其他方式测试相等性。

            衡量平等的不同方法:

            • 通过运行函数来测试返回值:

              fn1.compareFn() == fn2.compareFn() //true

            • 通过调用toString() 对源代码进行测试(注意:这在浏览器中不是标准化的!):

              fn1.compareFn.toString() == fn2.compareFn.toString() //true

            但是,由于它们是不同的实例(您没有调用 testFn == testFnfn1.compareFn == fn1.compareFn),它们引用了不同的内存位置,因此相等性测试结果为假。

            也可以在这个问题上找到更多信息:'how compare two static function are equal or not in javascript'。

            另外请注意,您应该使用三等号 (===) 而不是“双等号”,因为后者不测试类型的相等性(即检查 2 个变量是否都是数字,以及值为 5)。

            【讨论】:

            • 唯一有创意的答案!格拉茨!
            • @rafaelcastrocouto 谢谢,我有点太投入了;)
            猜你喜欢
            • 2019-01-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-09-30
            相关资源
            最近更新 更多