@@ -864,7 +864,90 @@ MYAPP.utilities.array = (function () {
864864
865865静态属性(包括私有和公有)有时候会非常方便,它们可以包含和具体实例无关的方法和数据,而不用在每次实例中再创建一次。当我们在第七章中讨论单例模式时,你可以看到使用静态属性实现类式单例构造函数的例子。
866866
867+ ##对象常量
867868
869+ JavaScript中是没有常量的,尽管在一些比较现代的环境中可能会提供` const ` 来创建常量。
868870
871+ 一种常用的解决办法是通过命名规范,让不应该变化的变量使用全大写。这个规范实际上也用在JavaScript原生对象中:
869872
873+ Math.PI; // 3.141592653589793
874+ Math.SQRT2; // 1.4142135623730951
875+ Number.MAX_VALUE; // 1.7976931348623157e+308
870876
877+ 你自己的常量也可以用这种规范,然后将它们作为静态属性加到构造函数中:
878+
879+ // constructor
880+ var Widget = function () {
881+ // implementation...
882+ };
883+
884+ // constants
885+ Widget.MAX_HEIGHT = 320;
886+ Widget.MAX_WIDTH = 480;
887+
888+ 同样的规范也适用于使用字面量创建的对象,常量会是使用大写名字的普通名字。
889+
890+ 如果你真的希望有一个不能被改变的值,那么可以创建一个私有属性,然后提供一个取值的方法(getter),但不给赋值的方法(setter)。这种方法在很多可以用命名规范解决的情况下可能有些矫枉过正,但不失为一种选择。
891+
892+ 下面是一个通过的` constant ` 对象的实现,它提供了这些方法:
893+
894+ - set(name, value)
895+
896+ 定义一个新的常量
897+ - isDefined(name)
898+
899+ 检查一个常量是否存在
900+ - get(name)
901+
902+ 取常量的值
903+
904+ 在这个实现中,只允许基本类型的值成为常量。同时还要使用` hasOwnproperty() ` 小心地处理那些恰好是原生属性的常量名,比如` toString ` 或者` hasOwnProperty ` ,然后给所有的常量名加上一个随机生成的前缀:
905+
906+ var constant = (function () {
907+ var constants = {},
908+ ownProp = Object.prototype.hasOwnProperty,
909+ allowed = {
910+ string: 1,
911+ number: 1,
912+ boolean: 1
913+ },
914+ prefix = (Math.random() + "_").slice(2);
915+ return {
916+ set: function (name, value) {
917+ if (this.isDefined(name)) {
918+ return false;
919+ }
920+ if (!ownProp.call(allowed, typeof value)) {
921+ return false;
922+ }
923+ constants[prefix + name] = value;
924+ return true;
925+ },
926+ isDefined: function (name) {
927+ return ownProp.call(constants, prefix + name);
928+ },
929+ get: function (name) {
930+ if (this.isDefined(name)) {
931+ return constants[prefix + name];
932+ }
933+ return null;
934+ }
935+ };
936+ }());
937+
938+ 测试这个实现:
939+
940+ // check if defined
941+ constant.isDefined("maxwidth"); // false
942+
943+ // define
944+ constant.set("maxwidth", 480); // true
945+
946+ // check again
947+ constant.isDefined("maxwidth"); // true
948+
949+ // attempt to redefine
950+ constant.set("maxwidth", 320); // false
951+
952+ // is the value still intact?
953+ constant.get("maxwidth"); // 480