Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/417.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么时候在Javascript闭包中使用return语句?_Javascript_Scope_Closures - Fatal编程技术网

什么时候在Javascript闭包中使用return语句?

什么时候在Javascript闭包中使用return语句?,javascript,scope,closures,Javascript,Scope,Closures,考虑第一个Javascript片段,它仅使用var和this来声明范围: var Bro = function() { var self = this; this.storyName = "story"; // public var storyType = "cool"; // private // private function var composeStory = function() { return storyType + '

考虑第一个Javascript片段,它仅使用var和this来声明范围:

var Bro = function() {
    var self = this;
    this.storyName = "story"; // public
    var storyType = "cool"; // private

    // private function
    var composeStory  = function() {
        return storyType + ' ' + self.storyName;
    };

    // privileged function
    this.tellStory = function() {
        console.log(composeStory() + ' bro!');
    };
};
与此相比,它使用return语句,并稍微修改了范围:

var Bro = function() {
    var self = this;
    this.storyName = "story"; // private?
    var storyType = "cool"; // private

    // private function
    var composeStory = function() {
        return storyType + ' ' + self.storyName;
    };

    // privileged variables/functions
    return {
        storyName: this.storyName,
        tellStory: function() {
            console.log(composeStory() + ' bro!');
        }
    };
}
我的问题是:

  • 什么时候你会使用第二种方法而不是第一种,或者这只是一种风格上的东西
  • 为什么第二个示例中的
    this.storyName
    是私有的,即使我将其设置为
    this
  • 我必须声明
    var self=this
    以访问两个私有函数中的
    范围。Javascript框架如何使
    this
    对象在其函数中可访问
  • 在第二个示例中,return语句中的
    storyName
    属性可以正确访问
    this
    范围。为什么它能做到这一点,而私人职能却不能做到

  • 我会回答第三个问题。它们使用
    call
    apply
    方法,这些方法可用于将第一个参数作为要执行函数的上下文的所有函数

    this.message = "hello ";
    var function(argument) {
        console.log(this.message + argument);
    }
    function.call(this, "world!");
    function.apply(this, ["world!"]);
    

    举一个更简洁的例子。

    问题4:在JS中,
    这个
    有函数作用域,而不是块作用域

    因此,在第二个示例中,在函数
    composeStory
    中,
    this
    具有函数
    composeStory
    的范围,而不是
    Bro
    的对象实例的范围。因此,您必须将
    保存为
    self
    ,因为
    的含义已更改

    (事实上,在函数
    组件
    中,
    通常是
    窗口
    ,或在严格模式下
    未定义
    。如果插入

    alert(this === window); 
    
    "use strict"; 
    alert(typeof this === "undefined"); 
    
    composeStory
    函数中,它将提示“true”。如果插入

    alert(this === window); 
    
    "use strict"; 
    alert(typeof this === "undefined"); 
    
    它将再次警告“true”。请参阅进一步。)

    在第二个示例的return语句中,
    不在函数内。所以
    这个
    仍然是指包含函数,即正在创建的
    Bro
    的实例。

    Javascript中没有“private”和“public”这样的东西。您看到的是对象属性和闭包捕获变量之间的差异。闭包捕获变量可用于隐藏状态,但它们将状态隐藏在附加到闭包作用域中创建的函数的不同对象上,而不是像在其他语言中一样,隐藏在返回的对象上。考虑到这一点,我将回答你的问题

    1) 我不会使用这两个表单,但它们在风格上很相似,都使用闭包捕获。但是,请注意,第一个使用构造函数模式,第二个使用工厂模式。第一种方法只有在调用Bro之前使用new关键字时才有效。第二种方法将忽略new创建的对象,而支持object literal创建的对象,但是您可以安全地调用它,而无需在其前面加上new前缀

    2) storyName不是私有的,它设置在不同的对象上。当函数以new作为前缀调用时,将创建一个新对象并作为“this”参数传入。这是您通过“This.storyName”设置的对象。然后,该对象被丢弃,取而代之的是您在文本中创建的对象。您看不到storyName,因为它未在返回的对象上设置

    3) 您可以在self之类的闭包变量中捕获它,也可以在函数上使用bind将其绑定到原始this。我更喜欢自己


    4) 这仍然在范围内,因为您正在构造函数中执行

    Crackford的“”将回答您关于JavaScript内部工作的这些问题和所有其他问题。这是JavaScript开发人员的必备书。您建议使用哪种形式?两者都不推荐。我建议使用传统的JavaScript构造函数模式。你能解释一下原因吗?与我给出的第一个版本相比,它有什么好处?它避免了为构造函数中的函数创建闭包。我会把它们分配给Bro的原型。使用上述代码构造一个对象的成本可能是它需要的3倍左右。