本地作用域的JavaScript(非常noob)

本地作用域的JavaScript(非常noob),javascript,Javascript,我正在努力学习JavaScript,我被范围限定所困扰 var payments = function () { var invoice = {}; return { init: function (Obj) { invoice = Obj; }, invoice : invoice }; }(); 我调用payments.init({foo:bar})。然后,如果我调用payments.invoi

我正在努力学习JavaScript,我被范围限定所困扰

var payments = function () {
    var invoice = {};
    return {
        init: function (Obj) {
            invoice = Obj;
        },
        invoice : invoice
    };
}();
我调用
payments.init({foo:bar})
。然后,如果我调用
payments.invoice
,它将返回
undefined
。但是调用
init
函数时应该搜索外部变量
invoice
。我做错了什么


我来自PHP,JavaScript中的OOP快把我逼疯了。

问题是
invoice
属性是按值分配的,而不是按引用分配的(JS没有按引用分配)

然后,当您更改变量
invoice
的值时,属性
invoice
的值不会神奇地更新

您可以尝试使用读取变量
invoice
的方法,而不是将
invoice
的值存储在数据属性中:

var payments = function () {
  var invoice = {};
  return {
    init: function (obj) { invoice = obj; },
    invoice: function() { return invoice; }
  }
}();
payments.init({foo: "bar"});
payments.invoice(); // {foo: "bar"}
或者使用getter属性:

var payments = function () {
  var invoice = {};
  return {
    init: function (obj) { invoice = obj; },
    get invoice() { return invoice; }
  }
}();
payments.init({foo: "bar"});
payments.invoice; // {foo: "bar"}

这是因为返回对象的
invoice
属性仍然指向初始对象。您已经更改了
发票
变量指向的对象,但没有更改模块对象

试着这样做:

var payments = function () {
    var module = {
        init: function (Obj) {
            module.invoice = Obj;
        },
        invoice: null
    };
    return module;
}();
var invoice={a:1}
var payments={
    init:function(obj){
        invoice=obj;
        console.log(invoice);
    },
    invoice:invoice
};
payments.init({foo:'bar'});//{foo:'bar'}
console.log(payments.invoice)//{a:1}
它是这样的:

var payments = function () {
    var module = {
        init: function (Obj) {
            module.invoice = Obj;
        },
        invoice: null
    };
    return module;
}();
var invoice={a:1}
var payments={
    init:function(obj){
        invoice=obj;
        console.log(invoice);
    },
    invoice:invoice
};
payments.init({foo:'bar'});//{foo:'bar'}
console.log(payments.invoice)//{a:1}

只为类使用大写名称是个好主意。这与
var payments=function(){var invoice={};return{init:function(Obj){this.invoice=Obj;},invoice:null};}()相同
Right?@RiccardoBarbotti否,因为它重新分配返回的模块对象的属性,而不仅仅是作用域为函数的局部变量。