如何在JavaScript中进行类自由继承(Crockford风格)

时间:2017-02-14 12:20:39

标签: javascript node.js class ecmascript-6

背景

我正在努力提高我的JS技能,并且我正在观察JS世界中的一些重要实体。这样的实体是道格拉斯·克罗克福德,他正在宣传一个免费的范式。

在Nordic js观看他之后(我强烈推荐)我对他makes objects的方式感到困惑,没有任何分类法。

问题

我现在正在尝试将他的幻灯片复制到一个使用例外的简单示例中,但我无法让它正常工作。

我不明白我的UniformityException.js文件如何重用Exception.js中的代码并与Crockford的意识形态保持一致。

这里的问题是specs中的UniformityException.js变量只有write方法,理所当然。

多次观看幻灯片后,我无法理解如何在不大量使用Object.assign的情况下更改此代码。

代码

Exception.js

"use strict";

let jsonfile = require("jsonfile");
let _ = require("underscore");

let Exception = function(args){

    let DEFAULT_PROPS = {
        exceptionName: "Exception",
        outputFolder: "./ErrorLogs/",
        fileExtension: ".txt"
    };

    DEFAULT_PROPS.message = "A generic exception occurred.";
    DEFAULT_PROPS.outputFile = DEFAULT_PROPS.exceptionName  + "_" + _.now();

    let props = Object.assign(DEFAULT_PROPS, args);

    let write = function(){
        jsonfile.writeFile(props.outputFolder + props.outputFile + props.fileExtension, props.message, error => {
            if(_.isNull(error) || _.isUndefined(error))
                console.log(error);
        });
    };

    return Object.freeze({
        write
    });
};

module.exports = Exception;

UniformityException.js

"use strict";

let Exception = require("./Exception.js");
let jsonfile = require("jsonfile");
let _ = require("underscore");

let UniformityException = function(args){

    let specs = Exception({
        exceptionName: "UniformityException",
        fileExtension: ".json"
    });

    let write = function(info){
        jsonfile.writeFile(specs.outputFolder + specs.outputFile, info, error => {
            if(_.isNull(error) || _.isUndefined(error))
                console.log(error);
        });
    };

    return Object.freeze({
        write
    });
};

module.exports = UniformityException;

index.js

"use strict";

let UniformityException = require("./Exceptions/UniformityException.js");

let myUniformException = UniformityException();

myUniformException.write({fruit: "banana"});

问题

  1. 如何让UniformityException.js以符合Crockford风格的方式重用Exception.js中的代码?
  2. 像往常一样,应避免使用newthisObject.create等关键字。

2 个答案:

答案 0 :(得分:1)

你需要什么

为此,您需要使用Destructuring assignment pattern。使用此模式,幻灯片中的以下代码:

function animal(spec) {
  let {body, type, name} = spec;
}

将转换为以下内容:

function animal(spec) {
    let body = spec.body;
    let type = spec.type;
    let name = spec.name;
}

这实际上是工厂模式的ECMA6版本,如本博文constructors VS factories中所述。

考虑到这一点,我们现在可以转到代码。

代码

<强> index.js

"use strict";

let _ = require("underscore");
let Exception = require("./Exceptions/Exception.js");
let UniformityException = require("./Exceptions/UniformityException.js");

let jsonParams = {
    outputFolder: "./ErrorLogs/",
    fileExtension: ".txt",
    message: {info: "A generic error ocurred."},
    exceptionName: "Exception",
};

let myException = Exception(jsonParams);
myException.write();

jsonParams.fileExtension  = ".json";
jsonParams.exceptionName = "UniformException";
jsonParams.outputFileName = jsonParams.exceptionName + "_" + _.now();

let myUniformException = UniformityException(jsonParams);
myUniformException.write({
    fruit: "banana"
});

<强> Exception.js

"use strict";

let jsonfile = require("jsonfile");
let _ = require("underscore");

let Exception = function(args) {
    let {
        outputFolder,
        fileExtension,
        exceptionName,
        message,
        outputFileName,
    } = args;

    outputFileName = outputFileName|| (exceptionName  + "_" + _.now());

    let filePath = outputFolder + outputFileName + fileExtension;

    let write = function() {
        jsonfile.writeFile(filePath, message, error => {
            if (!_.isNull(error) && !_.isUndefined(error))
                console.log(error);
        });
    };

    return Object.freeze({
        filePath,
        write
    });
};

module.exports = Exception;

<强> UniformityException.js

"use strict";

let Exception = require("./Exception.js");
let jsonfile = require("jsonfile");
let _ = require("underscore");

let UniformityException = function(args) {

    let {filePath} = Exception(args),

        write = function(info) {
            jsonfile.writeFile(filePath, info, error => {
                if (!_.isNull(error) && !_.isUndefined(error))
                    console.log(error);
            });
        };

    return Object.freeze({
        filePath,
        write
    });
};

module.exports = UniformityException;

我想指出的一点是,工厂函数应该都以小写字母开头function animal),并且可以遵循camelCase约定并将其命名为“{ {1}}”。

通常,按照惯例,需要使用animalConstructor()的构造函数是带有第一个大写字母(new)的名称。为避免将来出现混淆,您应该重命名例外。

其他

我强烈推荐的另一种资源来自邪恶帝国:

在我看来,这是对克罗克福德工厂职能的准确解释。

希望它有所帮助!

答案 1 :(得分:0)

你只能重复使用&#34;由Exception重新调整的内容。即如果您希望能够直接访问props,则需要公开它。没有办法解决它。

这实际上与您在其他基于类的语言中找到的可见性模型一致:私有成员(例如props)只能由类本身访问。如果一个儿童班应该有访问权限,许多语言都提供了一个受保护的&#34;模式,但JS没有类似的东西。

不是将它添加到函数返回的对象中,而是可以考虑让Exception接受它传递的函数&#34; private&#34;成员,就像Promise一样。不知道Crockford对此有何看法。