@@ -864,7 +864,90 @@ MYAPP.utilities.array = (function () {
864
864
865
865
静态属性(包括私有和公有)有时候会非常方便,它们可以包含和具体实例无关的方法和数据,而不用在每次实例中再创建一次。当我们在第七章中讨论单例模式时,你可以看到使用静态属性实现类式单例构造函数的例子。
866
866
867
+ ## 对象常量
867
868
869
+ JavaScript中是没有常量的,尽管在一些比较现代的环境中可能会提供` const ` 来创建常量。
868
870
871
+ 一种常用的解决办法是通过命名规范,让不应该变化的变量使用全大写。这个规范实际上也用在JavaScript原生对象中:
869
872
873
+ Math.PI; // 3.141592653589793
874
+ Math.SQRT2; // 1.4142135623730951
875
+ Number.MAX_VALUE; // 1.7976931348623157e+308
870
876
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
0 commit comments