将属性附加到函数对象是否安全/可接受?



假设我有一个函数

function foo() {
    var bar = true;
    if(bar) {
        //Do x
    }
}

在本例中,bar是某种条件,就像正则表达式一样。我希望它是全局可访问的,所以我可以改变条件并再次运行foo()。我可以把它变成一个全局变量:

var bar = true;
function foo() {
    if(bar) {
        //Do x
    }
}
foo();
bar = false;
foo();

或函数的实参:

function foo(bar) {
    if(bar) {
        //Do x
    }
}
foo(true);
foo(false);

或者一个单独的全局对象:

var foo_options = {
    bar: true
};
function foo() {
    if(foo_options.bar) {
        //Do x
    }
}
foo();
foo_options.bar = false;
foo();

我希望避免创建一个全局变量来保存条件,因为使用一个全局变量(即使它的名字很好)来保存实际上只在一个地方使用的东西似乎没有必要引起混乱。我不想传递条件作为参数,因为这个函数会被调用很多次我可能无法控制函数被调用的参数。全局对象似乎没有必要,原因与全局变量类似,但它也非常笨拙。

我目前正在考虑给foo()函数一个属性,这是可能的,因为JavaScript如何对待函数(以及几乎所有其他不是字符串或数字)作为对象:

function foo() {
    if(foo.bar) {
        //Do x
    }
}
foo.bar = true;
foo();
foo.bar = false;
foo();

我已经测试过了,这是可能的,但我担心这是一个好主意还是有任何危险。建议吗?

向默认对象添加属性通常是不受欢迎的,但是,只要您不替换标准属性(例如length),您应该没问题。

一个更简洁的解决方案是使用闭包来存储变量,使用函数工厂:
function makeFoo(foo_options){
    return function(){
      console.log("bar : ", foo_options.bar);
    }
}
var foo1 = makeFoo({bar:3}),
    foo2 = makeFoo({bar:0});
foo1(); // logs bar : 3
foo2(); // logs bar : 0

可以将函数和变量绑定到单个对象?更安全,不修改默认对象。

var myObject = {
    foo : 1234,
    bar : function(){
        console.log(this.foo)
    }
}
myObject.bar();

对于这个问题,函数工厂可能是最简单和最有意义的解决方案。一个不同的解决方案,如果你更喜欢"单例"而不是每次你想改变你的选项时都会创建新函数的函数工厂,将使用一个带有返回的"接口对象"的闭包:

var Foo = (function() {
  var bar = true;
  function foo() {
    if(bar) {
      //Do x
    }
  }
  return {
    setBar: function(b) {
      bar = b;
    },
    getBar: function() {
      return bar;
    },
    foo: foo
  };
}());
Foo.setBar(false);
Foo.foo();

最新更新