在javascript中使用getter和具有相同名称的函数

时间:2012-08-09 10:35:22

标签: javascript oop

我需要做一些改变但是继续提供向后兼容性一段时间,但我无法弄清楚如何实现这一点。

我有一个像这样的对象:

MyObject = (function() {
   // vars here and there

   var myVar

   // a bunch of code

   return {
     get myVar() { return myVar },
     myVar: function() { return myVar }
   }

}())

这不起作用。我希望能够通过

获得myVar
  

MyObject.myVar

  

MyObject.myVar()

有可能吗?更好的是,有没有可能实现这一点并使其跨浏览器兼容? (现在我知道Internet Explorer不支持 get 表示法)

感谢。

更新

因为似乎不可能,有没有办法制作我现在拥有的东西,get myVar()浏览器兼容Internet Explorer? 因此,所有浏览器都可以访问 MyObject.myVar

只要我能继续为myVar提供一个getter并且它与Internet Explorer兼容,就没有必要转移到myVar()但我找不到一个可行的解决方案来制作当前的方式(MyObject.myVar)除了转向类似函数的getter之外,它是兼容的。

4 个答案:

答案 0 :(得分:3)

不,这是不可能的。在javascript中,没有fieldsmethods的概念,只有对象的property,无论属性是值还是函数(函数也是对象)。

如果MyObject.myVar不是函数,则MyObject.myVar()将产生错误。

你唯一能做的就是有两个属性。

MyObject.myVar

MyObject.getMyVar()

答案 1 :(得分:1)

这是不可能的,因为它会含糊不清。 MyObject.myVar会调用getter,如果后跟(),则执行getter返回的对象。因此,当存在getter时,MyObject.myVar()具有含义,因此无法为解释器决定是否要调用函数。

答案 2 :(得分:1)

可能,虽然你的代码看起来很讨厌。由于函数是对象,因此它们也具有valueOf属性。利用对方法本身的引用来覆盖它,然后你就在那里:

var foo = (function()
{
    var bar = 'foobar';
    var r = {
        bar:function()
        {
            return bar;
        }
    };
    r.bar.toString = r.bar.valueOf = r.bar;//valueOf && toString invoke the method
    return r;
 })();

请注意,它的类型将是一个完全相同的对象,因此严格的比较将不起作用:

foo.bar =='foobar'//true
foo.bar === 'foobar'//false
alert(foo.bar+'');//alerts foobar
alert(foo.bar);//alerts foobar now, setting toString to reference the method, too
console.log(foo.bar());//foobar <= still works, and here strict comparisons do work

这可能会导致许多令人讨厌的虫子,这些虫子可能会让你刮伤头发,直到头发没有留下头发。更不用说可能最终维护你的代码的其他人了!

答案 3 :(得分:1)

我猜这有效:

  function test() {
      var myVar = 5;
      return {
      /*@cc_on
          /*@if (@_jscript_version)
              myVar: function() { return myVar }
          @else @*/
              get myVar() { return myVar }
          /*@end
      @*/
      };
  }

var a = test();
var b = a.myVar/*@cc_on () @*/

alert(b) // alerts 5

http://jsfiddle.net/XS7fU/2/