var utils = function() {
function getMyPrivateName() {
return "Caoimhin";
}
return {
messages: {
getMyPublicName: function getMyPublicName() {
return "Kevin";
},
sayHello: function() {
document.writeln("hello " + getMyPublicName() + "<br/>");
document.writeln("hello " + getMyPrivateName() + "<br/>");
}
}
};
} ();
utils.messages.sayHello();
我正在使用 javascript 命名空间,并遇到了意外的行为。我主要在 IE 中进行开发,因为这是我们 Intranet 应用程序的目标浏览器。
在 IE 中,当包含在空白页面上时,输出:
hello Kevin
hello Caoimhin
在 FF 中脚本遇到错误:
getMyPublicName is not defined
如果我注释掉有问题的行:
//document.writeln("hello " + getMyPublicName() + "<br/>");
FF 输出:
hello Caoimhin
所以我知道它可以访问私有(private)函数...
谁能解释一下为什么会发生这种情况?为了拥有与上面类似的跨浏览器解决方案,我需要做什么..
我知道我可以写这样的东西:
document.writeln("hello " + utils.messages.getMyPublicName() + "<br/>");
但我不想......
提前致谢, 凯文
最佳答案
您偶然发现了 IE 使用的 JScript 语言中的一个错误。
getMyPublicName: function getMyPublicName() {
...
},
这里的function getMyPublicName()
值是一个内联函数表达式,它被赋予了一个可选标识符getMyPublicName
,该标识符与其在所有者中的属性名称相同。 (sayHello
省略此标识符。)
根据 ECMAScript 标准,可选标识符应该做的是在标识符名称 getMyPublicName
下对函数体本身范围内可见的函数进行引用。这可用于创建引用自身的匿名内联函数(用于递归)。
它在 IE 中的错误做法是使该函数在父作用域中的名称 getMyPublicName
下可见(utils
函数) )。因为它在该作用域中可见,所以它对 sayHello 函数的子作用域也可见,从而使您的代码在不应该工作时正常工作。
您可以按照达斯汀的建议,使用 this.
正确获取对 getMyPublicName
的引用。或者,如果您想避免 JavaScript 中的 this
绑定(bind)问题(例如,因为您要将 sayHello
函数作为超时或事件的委托(delegate)传递) ,您可能更愿意将公共(public)函数也放在父作用域中:
var utils = function() {
function getMyPrivateName() {
return "Caoimhin";
}
function getMyPublicName() {
return "Kevin";
}
function sayHello() {
document.writeln("hello " + getMyPublicName() + "<br/>");
document.writeln("hello " + getMyPrivateName() + "<br/>");
}
return {
messages: {
getMyPublicName: getMyPublicName,
sayHello: sayHello,
}
}
}();
关于Javascript + 命名空间 + FF 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1836546/