据我所知,在JavaScript中没有很好的解决方案来建立私有成员。描述here的解决方案效率不高,因为私有成员成为对象的一部分,而不是原型,因此需要更多内存。
因此,我决定只使用Python实践 - 用前导下划线标记私有内容,让其他人知道makred属性或方法不打算从外部使用。
但是有一个众所周知的代码质量工具 - JSLint,它建议不使用前导或尾随下划线。
这背后的理由是什么?这只是代码风格的建议或下划线会导致更严重的问题吗?如果它只是JS社区中的代码样式约定,它有多强大?
答案 0 :(得分:4)
JSLint是一个很好的工具,但它表达了对作者风格的编码实践的看法。 Read about what those preferences are here。 JavaScript解析器在使用前导下划线/下划线时没有任何损害,该工具被编程为将此视为不良约定并警告您不要使用它。如果使用前导下划线是您的首选,并且有意义,请使用它们。
如果您不希望在使用以下划线/下划线开头的标识符时在JSLint中看到警告,则JSLint中有一个设置可以隐藏这些警告。如本示例所示,包装您不想评估的代码,您将看不到警告:
/*jslint nomen: true */
var _gaq = {};
/*jslint nomen: false */
如果您正在从文件中评估代码,则情况确实如此,但如果您在JSLint网站上,则可以选择“容忍...在标识符中悬空_”也会删除警告。
请注意,这样做可能会导致JSHint解析文件的问题。请查看此链接,其中显示与该标志相关的JSLint vs JSHint。但是,如果你要通过JSLint标准混合使用JSHint会引起一些混乱。
不使用闭包,JavaScript中不存在私有变量,但它不是每个项目执行所需的模式。如果您想了解有关JavaScript中闭包的更多信息,请查看Ben Nadel's wonderful blog post和NetTuts+
答案 1 :(得分:1)
这只是代码风格的建议。 您可以使用JSHint代替,并按照项目/公司中的代码样式进行设置。 至于我,如果用这种方式标记私人成员,没有什么不好的。主要规则应该是遵循整个项目中的统一惯例。如果这使您的代码更具可读性和可维护性,那么您可以自由地遵循当前项目的约定。
答案 2 :(得分:0)
下划线前缀可用作约定。但这只是一个惯例。
如果私有成员是对象实例的属性,唯一的方法是在构造函数中声明变量。对象的属性永远不会在原型中注册。如果您在proto中存储属性,则其值与所有其他实例共享。 它像“公安条例”中的静力学一样工作。
原型仅用于解决实例中的未定义属性。
例:
function O(){}
O.prototype.name = "John";
var o = new O;
// o look like that :
// {
// __proto__: { name: "John"}
// }
console.log(o.name); // write "John"
o.name = "Tom";
// now :
// {
// name: "Tom",
// __poto__: { name: "John" }
// }
console.log(o.name); // write "Tom"
实例上name的定义不会覆盖原型值。它只存储在级联分辨率中的proto值之前的实例中。
抱歉我的英语不好。