如何在JavaScript中进行无类继承(Crockford风格) 背景

如何在JavaScript中进行无类继承(Crockford风格) 背景,javascript,node.js,class,ecmascript-6,Javascript,Node.js,Class,Ecmascript 6,我正在努力提高我的JS技能,并以此来观察JS世界中的一些大型实体。这样一个实体就是道格拉斯·克罗克福德,他正在宣扬一种无阶级的范式 在Nordic js(我强烈推荐)看了他之后,我对他没有任何分类的方式感到困惑 问题 我现在正试图将他的幻灯片复制到一个使用异常的简单示例中,但我无法让它正常工作 我不明白我的UniformityException.js文件如何重用Exception.js中的代码,并与Crockford的思想保持一致 这里的问题是,UniformityException.js中的s

我正在努力提高我的JS技能,并以此来观察JS世界中的一些大型实体。这样一个实体就是道格拉斯·克罗克福德,他正在宣扬一种无阶级的范式

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

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

我不明白我的
UniformityException.js
文件如何重用
Exception.js
中的代码,并与Crockford的思想保持一致

这里的问题是,
UniformityException.js
中的
specs
变量只有一个
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;
"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;
"use strict";

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

let myUniformException = UniformityException();

myUniformException.write({fruit: "banana"});
"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"
});
"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;
"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;
UniformityException.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;
"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;
"use strict";

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

let myUniformException = UniformityException();

myUniformException.write({fruit: "banana"});
"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"
});
"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;
"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;
index.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;
"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;
"use strict";

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

let myUniformException = UniformityException();

myUniformException.write({fruit: "banana"});
"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"
});
"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;
"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;
问题
  • 如何使
    UniformityException.js
    以符合Crockford风格的方式重用
    Exception.js
    中的代码
  • 通常,要避免使用诸如
    new
    this
    Object.create
    之类的关键字。

    您只能“重用”由
    异常
    返回的内容。也就是说,如果你想直接访问
    道具
    ,你需要公开它。这是没有办法的

    这实际上与您在其他基于类的语言中发现的可见性模型是一致的:私有成员(例如,
    props
    )只能由类本身访问。如果一个子类应该有访问权限,许多语言都提供“受保护”模式,但JS没有类似的功能


    < >不要将它添加到函数返回的对象中,可以考虑让<代码>异常接受它传递其“私有”成员的函数,就像<代码>承诺>代码>。不过我不确定克罗克福德是怎么说的。

    你需要什么 为了做到这一点,您需要使用。使用此模式,幻灯片中的以下代码:

    function animal(spec) {
      let {body, type, name} = spec;
    }
    
    将转换为以下内容:

    function animal(spec) {
        let body = spec.body;
        let type = spec.type;
        let name = spec.name;
    }
    
    这实际上是工厂模式的ECMA6版本,如本文所述

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

    代码 index.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;
    
    "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;
    
    "use strict";
    
    let UniformityException = require("./Exceptions/UniformityException.js");
    
    let myUniformException = UniformityException();
    
    myUniformException.write({fruit: "banana"});
    
    "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"
    });
    
    "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;
    
    "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;
    
    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;
    
    "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;
    
    "use strict";
    
    let UniformityException = require("./Exceptions/UniformityException.js");
    
    let myUniformException = UniformityException();
    
    myUniformException.write({fruit: "banana"});
    
    "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"
    });
    
    "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;
    
    "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;
    
    UniformityException.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;
    
    "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;
    
    "use strict";
    
    let UniformityException = require("./Exceptions/UniformityException.js");
    
    let myUniformException = UniformityException();
    
    myUniformException.write({fruit: "banana"});
    
    "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"
    });
    
    "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;
    
    "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约定,将其命名为“
    animalConstructor()

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

    附加的 我还极力推荐的另一个资源来自邪恶帝国:

    我认为这是对Crockford工厂功能的准确解释


    希望有帮助

    你想重复使用哪一部分?
    write
    功能?一切。但是在本例中,我想将
    Exception.js
    中的
    props
    变量与上述代码一起重用,因为
    Expection
    公开的唯一属性是
    write
    props
    是其构造函数中的私有变量。如果您想让该部分公开,您必须将其添加到return(freezed)对象中。“没有任何分类”——这是不对的。出于某种原因,他不使用原型继承。他的函数(我敢称之为类?)确实有层次结构。在你的例子中,
    UniformityException
    无法扩展
    Exception
    ,因为它的
    write
    方法是不可重用的。我不明白为什么公开
    props
    会违反大克劳福德的“不可撤销”法则。这基本上就是
    {other}=other_构造函数(spec)
    在他的幻灯片中所做的。另一方面:有很多人不服从“JS教父”,仍然是伟大的开发者!过于教条不会让你在任何语言中都成为一名更好的开发人员:)我重新做了我的答案,我希望你喜欢,Flame@Flame_Phoenix“为了做到这一点,你需要使用解构分配模式。”你在说什么?解构分配不会启用以前不可能启用的任何功能。这是误导。整个答案似乎都集中在如何做某事而不是做什么。据我所知,重要的部分是在
    异常
    对象上导出
    文件路径
    (这基本上就是我写的,也就是说,只有公开的内容可以重用)。Soldeplata的答案比你的好得多,因为它清楚地回答了我的问题。