什么时候在Javascript闭包中使用return语句?
考虑第一个Javascript片段,它仅使用var和this来声明范围:什么时候在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 + '
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
对象在其函数中可访问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倍左右。