Javascript模块控件

Javascript模块控件,javascript,module,return,Javascript,Module,Return,我目前正在处理模块,但我的困惑是,当我在函数中编写return对象时,它可以在函数范围外调用,但当我编写标准对象,如var obj={some:something}时,它就不能在函数范围外调用。为什么和如何 //返回对象 var-ray=(函数(){ 返回{ 讲:函数(){ 控制台日志(“Haseeb”); } }; })(); 雷,说吧; //标准对象 var-ray=(函数(){ var obj={ 讲:函数(){ 控制台日志(“Haseeb”); } } })(); o

我目前正在处理模块,但我的困惑是,当我在函数中编写
return
对象时,它可以在函数范围外调用,但当我编写标准对象,如
var obj={some:something}
时,它就不能在函数范围外调用。为什么和如何

//返回对象
var-ray=(函数(){
返回{
讲:函数(){
控制台日志(“Haseeb”);
}
};
})();
雷,说吧;
//标准对象
var-ray=(函数(){
var obj={
讲:函数(){
控制台日志(“Haseeb”);
}         
}
})();
obj.speak()
假设您打算编写
ray.speak()而不是
obj.speak()

在这个代码段中,当执行匿名函数时,它会将nothing返回到
ray
变量,因此当您尝试从
ray
访问
speak()
方法时,它会抛出一个错误,说
无法读取未定义的
的属性“speak”

但是在您的第一个代码片段中,匿名函数确实使用
speak
方法返回了一个对象,因此您可以调用,
ray.speak()

这不起作用,因为词法作用域是如何工作的。外部的Obj与函数内部定义的内容没有上下文关系,因为Obj是在函数的块范围内声明的。但是,如果obj声明在同一范围内,它将按预期工作

 var obj;
 // Standard Object
var ray = (function(){
       obj = {
           speak: function (){
            console.log("Haseeb");
        }         
    }
})();

obj.speak();
ray.speak()
将无法工作,因为它没有与obj的绑定。
return obj={…}
将是解决此问题的方法。

了解JavaScript变量范围将有助于:

现在来看看你的代码。 在第一个代码段中,变量“ray”被分配了自执行函数返回的值,该函数是返回的对象。与此类似:

var ray = {
        speak: function (){
            console.log("Haseeb");
        }
    };
因此,下面的语句是有效的,因为“ray”有一个属性“speak”

ray.speak(); 
但是,在代码段的第二部分中,自执行函数不返回任何内容,因此类似于:

var ray = undefined;
现在语句“
ray.speak()
”与执行“
undefined.speak()
”相同,这显然会引发错误

此外,执行
obj.speak
与执行“
undefined.speak()
”相同,因为变量“obj”仅在该自执行函数中可用。在功能之外,未定义“obj”

希望这有帮助。:)

编辑:

关于返回声明问题的解释:

return语句返回前面的代码/语句的输出

示例:

var a = 2;
return a; // will return a's value, i.e. '2'

var obj = { x:1 };
return obj; // will return the obj variable's value i.e. { x:1 }

var a = 1;
return a > 1; // will return false i.e. what 'a > 1' outputs after execution
所以如果你写

return obj = { x:1 }; 
这将返回赋值'obj={x:1}'输出的内容,即obj的赋值

现在来看看你的代码

var ray = (function(){
        return obj = {
           speak: function (){
            console.log("Haseeb");
        }         
    }
})();
在这里,return语句不会使obj对函数外部的作用域可用,它只返回obj的值,然后将该值赋给“ray”。 之所以能够执行
obj.speak()
,而不获得任何异常,是因为您使用了变量obj,而没有使用“var”关键字在函数中声明它,这会导致在全局范围中自动声明“obj”。这就是为什么您也可以访问函数外部的“obj”

如果将代码更改为:

var ray = (function(){
    var obj;
    return obj = {
           speak: function (){
            console.log("Haseeb");
        }         
    }
})();
尝试在函数外部执行
obj.speak()
时将出现异常。因为“obj”现在已声明,并且仅在函数内部可用

我建议阅读更多关于JavaScript中变量作用域的教程,并在控制台上玩一玩。:)


希望这有帮助:)

如果您不在函数中声明obj,那么它将成为窗口对象。如果我声明ray.obj呢?与top ray.speake类似,因为您不返回任何内容,所以ray将是未定义的。最好从对象声明中删除
var
。你的意思是如果我返回obj,那么它就可以在函数范围外调用?但不是像这样,雷,你会说话吗?它可以称为ray.speak或obj.speak why和how?仍然有点困惑在第二个示例中,您需要返回
obj
。您可以使用ray.speak();这很好,很有帮助,我理解:)但是有一个困惑,当我使用return obj={speak:function(){}时,它可以在范围之外工作,就像这个ray.speak,这意味着根据你的var ray={speak:function(){},但还有一件事它也可以称为obj.speak,那么如何区分ray.speak和obj.speak这两个speak的对象呢?在许多情况下,在写入返回obj={}object之后,我会尝试检查console.log上的一些东西,其中有些东西不能像console.log(ray.speak());console.log(obj.speak());console.log(ray.obj)那样工作;这是我写的代码片段var-ray=(function(){return obj={speak:function(){return console.log(“Haseeb”);}}}}}}();我已经编辑了答案,包括对您的困惑的解释。如果您认为答案澄清了您的疑问,请接受它。:)是的,我理解
var ray = (function(){
        return obj = {
           speak: function (){
            console.log("Haseeb");
        }         
    }
})();
var ray = (function(){
    var obj;
    return obj = {
           speak: function (){
            console.log("Haseeb");
        }         
    }
})();