考虑这个第一个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;
才能访问两个私有函数中的this
范围。 Javascript框架如何使this
对象在其函数内可访问?storyName
属性可以正确访问this
范围。为什么它可以这样做,当私人功能不能?答案 0 :(得分:0)
我将在第三个问题上回答。他们使用call
和apply
方法可用于所有函数,这些函数将第一个参数作为函数执行的上下文。
this.message = "hello ";
var function(argument) {
console.log(this.message + argument);
}
function.call(this, "world!");
function.apply(this, ["world!"]);
更简洁的例子see jQuery source。
答案 1 :(得分:0)
问题4:在JS中,this
具有功能范围,而不是块范围。
因此,在第二个示例中,在函数composeStory
中,this
具有函数composeStory
的范围,而不是Bro
的对象实例的范围。因此,您必须将this
保存为self
,因为this
的含义已更改。
(事实上,在函数composeStory
中,this
通常是window
,或者是严格模式undefined
。如果插入
alert(this === window);
在composeStory
函数中,它会提醒“true”。如果你插入
"use strict";
alert(typeof this === "undefined");
它将再次警告“真实”。进一步查看here。)
在第二个示例的return语句中,this
不在函数内。所以this
仍然引用包含函数,即正在创建的Bro
的实例。
答案 2 :(得分:0)
Javascript中没有“私人”和“公共”这样的东西。您所看到的是对象的属性与闭包捕获的变量之间的区别。闭包捕获变量可用于隐藏状态,但它们将其隐藏在附加到闭包作用域中创建的函数的不同对象上,而不是在返回的对象上,就像在其他语言中一样。考虑到这一点,我会回答你的问题,
1)我不会使用任何一种形式,但它们在风格上相似,都使用闭包捕获。但是请注意,第一个使用构造函数模式,第二个使用工厂模式。第一个只有在调用Bro之前使用new关键字才有效。第二个将忽略new创建的对象,而不是对象文字创建的对象,但你可以安全地调用它而不用新的前缀。
2)storyName不是私有的,它设置在不同的对象上。当一个函数被调用前缀为new时,会创建一个新对象并将其作为“this”参数传入。这是您通过“this.storyName”设置的对象。然后丢弃此对象,以支持您在文字中创建的对象。您没有看到storyName,因为它没有在返回的对象上设置。
3)你可以在像self这样的闭包变量中捕获它,或者在函数上使用bind将它绑定到原始的。我更喜欢自己关闭捕获。
4)这仍然在范围内,因为您正在构造函数中执行。