《JavaScript 模式》读书笔记(5)— 对象创建模式4

我们学完了大部分对象创建模式相关的内容,下面还有一些小而精的部分。七、对象常量JavaScript中没有常量的概念,虽然许多现代的编程环境可能为您提供了用以创建常量的const语句。作为一种变通方

大家好,又见面了,我是你们的朋友全栈君。

  我们学完了大部分对象创建模式相关的内容,下面还有一些小而精的部分。

 

七、对象常量

  JavaScript中没有常量的概念,虽然许多现代的编程环境可能为您提供了用以创建常量的const语句。作为一种变通方案,JavaScript中常见的一种方法是使用命名约定,使那些不应该被修改的变量全部用大写字母以突出显示。实际上这个命名约定已经用于内置JavaScript对象中了。

console.log(Math.PI);
console.log(Math.SQRT2);

  对于您自己的常量,也可以采用相同的命名约定,并且将它们以静态属性的方式添加到构造函数中。

// 构造函数
var Widget = function () {
    // 实现...
};

// 常数
Widget.MAX_HEIGHT = 320;
Widget.MAX_WIDTH = 480;

  同样的命名约定还可应用于以字面量创建的对象中,这些常量可以是以大写字母命名的正常属性。

  如果你真的想拥有一个不可变的值,可以创建一个私有属性并提供一个取值(getter)方法,但并不提供设值函数(setter)。不过在许多情况下,当可以采用简单的命名公约取值时,这种不提供设置函数的方法可能显得矫枉过正。

  下面是一个通用的constant(常量)对象实现方法示例,它提供了下列方法:

  set(name, value)

    定义一个新的常量。

  isDefined(name)

    检测是定常量是否存在。

  get(name)

    读取指定常量的值。

  在这个实现中,只有原始值(primitive value)允许设为常量。此外,一些额外的注意事项是要确保声明的常量与内置属性名不会冲突,比如toString或hasOwnProperty等,可以通过使用hasOwnProperty()检测名称,并且在所有的常量名前面添加随机生成的前缀,从而确保名称之间相互适应。

var constant = (function () {
    var constants = {},
        ownProp = Object.prototype.hasOwnProperty,
        allowed = {
            string:1,
            number:1,
            boolean:1
        },
        prefix = (Math.random() + "_").slice(2);
    
    return {
        set:function(name,value) {
            if(this.isDefined(name)) {
                return false;
            }
            if(!ownProp.call(allowed,typeof value)){
                return false;
            }
            constants[prefix + name] = value;
            return true;
        },
        isDefined:function(name) {
            return ownProp.call(constants,prefix + name);
        },
        get:function(name) {
            if(this.isDefined(name)){
                return constants[prefix + name];
            }
            return null;
        }
    }
}());

// 测试以上实现代码
// 检查是否已经定义
constant.isDefined("maxwidth");

// 定义
constant.set('maxwidth',480);

// 再次检查
constant.isDefined('maxwidth');

// 试图重新定义
constant.set("maxwidth",320);

// 该值是否扔保持不变
constant.get("maxwidth");

  

八、链模式

  链模式(Chaining Pattern)可以使您能够一个接一个的调用对象的方法,而无需将前一个操作返回的值赋给变量,并且无需将您的调用分割成多行:

myobj.method1("hello").method2().method3("world").method4();

  当创建的方法返回的是无任何意义的值时,可以使它们返回this,即正在使用的对象的示例。这将使对象的用户调用前面连接的下一个方法:

var obj = {
    value:1,
    increment: function () {
        this.value += 1;
        return this;
    },
    add: function(v) {
        this.value += v;
        return this;
    },
    shout:function () {
        alert(this.value);
    }
};

// 链方法调用
obj.increment().add(3).shout();

  

链模式的优点和缺点

  使用链模式的一个优点在于可以节省一些输入的字符,并且还可以创建更简洁的代码,使其读起来就像一个句子。

  另一个优点在于它可以帮助您考虑分割函数,以创建更加简短、具有特定功能的函数,而不是创建尝试实现太多功能的函数。从长远来看,这提高了代码的可维护性。

  链模式的一个缺点在于以这种方式编写的代码更加难以调试。或许直到在某个特定的代码行中发生错误,但是在此行中实际执行了太多步骤。当链中多个方法其中一个静默失效时,无法直到是哪一个方法失效了。

  在任何情况下,识别出这种模式都很有好处。当编写的方法并没有明显和有意义的返回值时,可以总是返回this。该模式得到了广泛的应用,比如在jQuery库中就使用了该模式。此外,如果查看DOM的API,那么还可以注意到它的结构也倾向于链模式。

 

九、method()方法

  JavaScript可能会使用那些以类的方式思考的程序员感到困惑。这就是为什么一些开发人员倾向于选择使JavaScript更加类似类。其中一个这样的尝试是Douglas Crockford引入method()方法的思想。现在回想起来,他承认使JavaScript类似类的思想并不是值得推荐的方案,但是它仍然是一种令人关注的模式,有可能在一些应用程序中遇到这种模式。

  使用构造函数看起来就像是在使用Java中的类。它们还能够支持您向构造函数主体中的this 添加实例属性。然后这种向this添加方法的机制其实效率十分低下,原因在于它们最终都会与每个实例一起被重新创建,并且消耗更多的内存空间。这也就是为什么可服用方法应该添加到构造函数的prototype属性中的原因。

  向编程语言中添加便利的功能通常也称之为语法糖。在这种情况下,method()方法也可以称之为“糖方法(sugar method)”。

  使用method()定义类的方法形式如下:

var Person = function (name) {
    this.name = name;
}.
    method('getName',function() {
        return this.name
    }).
    method('setName',function(name) {
        this.name = name;
        return this;
    })

  请注意构造函数是如何连接到method()的调用,其依次连接到下一个method()的调用,后面以此类推。这个例子遵循了前面介绍的链模式,它可以帮助您以单个声明语句定义整个“类”。

  method()方法有两个参数:新方法的名称、方法的实现。

var a = new Person('Adam');
a.getName();
a.setName('Eve').getName();
// 再次强调,请注意链模式已经生效,这是因为setName()返回了this,从而使得以上代码可以正常运行。

// 最后,我们看一下method()方法是如何实现的:

if(typeof Function.prototype.metho !== 'function') {
    Function.prototype.method = function (name,implementation) {
        this.prototype[name] = implementation;
        return this;
    };
}

  在method()的实现中,首先我们应该认真的检查该方法是否已经实现过。如果没有,那么继续添加函数,并将其作为implementation参数传递给构造函数的原型。在这种情况下,this指的是构造函数,其原型得到了增强。

 

  对象创建模式的内容到这里就告一段落了,这一整章文章讲解了命名空间模式、声明依赖、私有模式、模块模式以及沙箱模式、对象常量、链模式等一系列有用的创建对象的方法。那么下一章,我们会学习下代码复用模式。很重要哦。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/124385.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • API接口重复提交

    API接口重复提交

    2021年11月6日
    40
  • getter和setter怎么用_python setter

    getter和setter怎么用_python setter有时候我们只知道一个对象的字段,我们想通过反射的方式将此字段赋值,可直接写反射又太浪费时间,还需要自己手动拼接方法名,而java为我们提供了一个很方便的类(PropertyDescriptor)来操作这一过程。使用很简单,直接看代码:代码importcom.pibgstar.demo.bean.User;importjava.beans.IntrospectionException…

    2022年10月1日
    0
  • 散列查找

    散列查找一、散列的概念       散列同顺序、链接和索引一样,是又一种数据存储方法。散列存储的方法是:以数据集合中的每个元素的关键字k为自变量,通过一种函数h(k)计算出函数值,把这个值用做一块连续存储空间(即数组或文件空间)中的元素存储位置(即下标),将该元素存储到这个下标位置上。散列存储中使用的函数h(k)被称为散列函数或哈希函数,它实现关键字到存储位置(地址)的映射(或称转换),h(

    2022年5月14日
    63
  • webhosting什么意思_总带宽

    webhosting什么意思_总带宽Whenchoosingahost,theamountofbandwidthyoupurchasecanbecrucialtothesuccessofyoursite.Generallyspeaking,themorebandwidthyouhave,themoretrafficyoursitewillbeabletohandl…

    2022年10月8日
    2
  • Java中&和&&,|和||的区别(超详细讲解),细节请必会!

    Java中&和&&,|和||的区别(超详细讲解),细节请必会!一、&是与,&&是短路与&&是左边条件不满足就终止了,不会继续计算右边条件;而&是无论左边是否满足都会继续执行右边。比如a&&b,假如计算a是假,那么就不会继续计算b的真假值了;假如a是真,那么会继续计算b,当b也是真时,a&&b为真。而a&b,无论a是真假,都会继续计算…

    2022年7月9日
    24
  • webpack基础打包命令_逆向webpack打包后的js

    webpack基础打包命令_逆向webpack打包后的js没有配置文件的打包如果我们没有使用配置文件webpack.config.js,那么我们就需要通过命令来打包案例我们首先创建一个webpackTest文件夹,然后在文件夹中再创建2个子文件夹dis

    2022年7月29日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号