Javascript 解释以下JS代码(闭包)的行为

Javascript 解释以下JS代码(闭包)的行为,javascript,closures,iife,Javascript,Closures,Iife,我想知道为什么会有这样一种奇怪的行为,一个变量应该是一样的 myfun = (function() { var variableOne = 10; get = function(){ return variableOne; } set = function(value){ variableOne = value; }

我想知道为什么会有这样一种奇怪的行为,一个变量应该是一样的

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10

为什么variableOne的值没有更改为90。

ES6速记对象文本
{variableOne}
创建一个对象属性,该属性从局部变量
variableOne
复制值。一旦被复制,它就过着独立的生活。它不允许您访问局部变量

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
如果希望保留对局部值的引用,则需要远离基本变量,而是使用具有属性
variableOne
的对象。这样,您就不会将其值复制到返回的属性中:现在您在
get
方法中返回的是该属性的值本身:

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
myfun=(函数(){
返回{
变量一:10,
get:function(){
返回这个.variableOne;
},
设置:函数(值){
this.variableOne=值;
}
};
})();
//控制台窗口输出
console.log(myfun.variableOne);//10
myfun.variableOne=90;

console.log(myfun.get());//90
ES6速记对象文字
{variableOne}
创建一个对象属性,该属性复制本地变量
variableOne
的值。一旦被复制,它就过着独立的生活。它不允许您访问局部变量

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
如果希望保留对局部值的引用,则需要远离基本变量,而是使用具有属性
variableOne
的对象。这样,您就不会将其值复制到返回的属性中:现在您在
get
方法中返回的是该属性的值本身:

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
myfun=(函数(){
返回{
变量一:10,
get:function(){
返回这个.variableOne;
},
设置:函数(值){
this.variableOne=值;
}
};
})();
//控制台窗口输出
console.log(myfun.variableOne);//10
myfun.variableOne=90;

console.log(myfun.get());//90
之所以会发生这种情况,是因为
variableOne
是一个基本值-基本值是通过值复制的,而不是通过引用,因此一旦
中的赋值返回
(这是通过使用“object literal property value速记”创建属性的方式,而不是解构赋值)完成后,这是两个独立的变量。另一方面,正如我所说,对象是通过引用复制的,但是您仍然可以通过使用赋值运算符来更改引用本身(您可以在这里的另一个SO问题中阅读更多关于这一点的内容:)

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
更重要的是,
get
方法访问返回对象之外的
variableOne
,该对象是在闭包中定义的(即使闭包已经执行,它仍然有效)

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10

set
方法实际上不是属性设置器,因为创建
setter
需要传递属性名称。在本例中,这只是另一种常规对象方法。

发生这种情况是因为
variableOne
是一个基元值-基元值是通过值复制的,而不是通过引用,因此一旦
中的赋值返回
(通过使用“object literal property value速记”,而不是解构赋值),这两个变量现在是两个独立的变量。另一方面,正如我所说,对象是通过引用复制的,但您仍然可以使用赋值运算符更改引用本身(您可以在此处的另一个SO问题中了解更多信息:)

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10
更重要的是,
get
方法访问返回对象之外的
variableOne
,该对象是在闭包中定义的(即使闭包已经执行,它仍然有效)

myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10

set
方法实际上不是一个属性设置器,因为创建
setter
需要传递属性名称。在这种情况下,这只是另一个常规对象方法。

这不是一个分解赋值。这不是一个分解赋值。因为您更改了对象属性,而不是变量。Bec因为您更改了对象属性,而不是变量。
myfun = (function() {
            var variableOne = 10;
            get = function(){
            return variableOne;
            }
            set = function(value){
            variableOne = value;
            }
            return {variableOne,set,get};
            })();
        // Console Window Output
        console.log(myfun.variableOne);    
        >>10
        myfun.variableOne = 90;
        myfun.get()
        >>10