简体   繁体   English

调用方法的方法(如果存在)

[英]Call the method of a method if it exists

First I should point out that I'm new at both JS and node.js. 首先,我应该指出,我是JS和node.js的新手。 I'm trying to write a node.js chat bot, currently working at commands. 我正在尝试编写一个node.js聊天机器人,目前正在使用命令。

My problem is with calling a method of a method .. if that's even possible. 我的问题是调用方法的方法..如果可能的话。 This is the relevant part : 这是相关的部分:

    var text; // received message from user
    var userId; // Id of the user, number.
    if (cmd.hasOwnProperty(text.split(' ')[0])) { // Message will be a string, it should be ignore if the first word is not a command name.
        console.log("[Inc]" + userId + ": " + text)
        if (text.split(' ').length === 1) { // If the command name is not followed by any arguments then the only argument passed should be the userID(used to send replies to the user).
            cmd[text.split(' ')[0]](userId)
        } else {
            var args = [] // Placing all args in  an array because the commands will take different number of arguments, a calculator command for example could take a lot of args.
            for (var i = 1; i < text.split(' ').length; i++) {
                args.push(text.split(' ')[i])
            }
            console.log(args)
            cmd[text.split(' ')[0]](userId, args)
        }   
    } else {
        console.log("Command not found, try again");    
    }
    var cmd = {
        help : function () {
            cookies : function () { // 
                console.log('Cookies recipe')
            }
            if (arguments.length === 1) {
            console.log('General help text');
            } else if (help.hasOwnProperty(arguments[1])) { 
                this[arguments[0]](); // Seems my problem was here, this was creating the reference error.
            } else {
                console.log('Requested topic not found')
            }   
        },
        invite : function(id) { 
            send_PRIVGRP_INVITE(id)
        }   

    }

Any ideas how I could make this work, or is there some better way, cleaner way to do this. 关于如何进行此工作的任何想法,或者是否有更好的方法,更干净的方法来执行此操作。 Also I should mention I chose to use commands as objects and methods because some commands will be more complex and I was planing to giving them their on file.js and exporting it to the main.js file and it would be a lot easier to add commands w/o editing the main file all the time. 我还要提到我选择使用命令作为对象和方法,因为有些命令会更复杂,并且我打算将它们放在file.js上并将其导出到main.js文件中,添加起来会容易得多命令始终不编辑主文件。

Keep in mind I'm quite new at this, a detailed explanation would go a long way, thank you. 请记住,我对此很陌生,详细的解释将有很长的路要走,谢谢。

I think the code below gives the behavior you're looking for, but it's pretty antipattern. 我认为以下代码提供了您正在寻找的行为,但这是非常反模式的。 It's sort of object oriented looking , but it's really not, since it's defining the cookies function this same way inside each call of the containing function. 这是一种面向对象的外观 ,但实际上不是,因为它在包含函数的每次调用中都以相同的方式定义了cookies函数。 You probably want cookies to live on cmd , but that's not what your question asks. 您可能希望cookies驻留在cmd ,但这不是您的问题所要问的。

I think you eventually are going to inch into doing some real object oriented stuff, where you'll have a constructor set up all the properties for your functions within functions . 我认为您最终会精打细算地做一些面向对象的工作,在这里您将有一个构造函数来设置函数中函数的所有属性 That is, you'll want to leave JSON notation and run this as "real code" inside of an object constructor returning instances of cmd that you might initialize in different ways (maybe with JSON notation!). 也就是说,您将需要保留JSON表示法,并在对象构造函数中以“真实代码”的形式运行它,以返回可以用不同方式初始化(​​可能使用JSON表示法!)的cmd实例。

If this isn't what you wanted, drop a comment, and I'll revise. 如果这不是您想要的,请发表评论,我会进行修改。 Again, I wouldn't actually use this code in production. 同样,我不会在生产中实际使用此代码。 Antipattern. 反模式。

var cmd = {
    help: function () {
        var context = this.help;
        context.cookies = function () {
            console.log('Cookies recipe');
        };

        if (arguments.length === 0) {
            console.log('General help text');
        } else if (context.hasOwnProperty(arguments[0])) {
            context[arguments[0]]();
        } else {
            console.log('Requested topic not found');
        }
    },

    invite: function(id) {
        //send_PRIVGRP_INVITE(id);
        console.log("send_PRIVGRP_INVITE(" + id + ");");
    }
};

cmd.help();
cmd.help("cookies");
cmd.help("milk");
cmd.invite("wack");
cmd.help("invite");

That will produce this output: 这将产生以下输出:

General help text
Cookies recipe
Requested topic not found
send_PRIVGRP_INVITE(wack);
Requested topic not found

EDIT: There's some good information on how to use this here: 编辑:有一个关于如何使用一些好的信息, this在这里:

The quick take-home is that this refers to the function's execution context , as the SO answer quotes ... 快速了解一下, this是指函数的执行上下文 ,因为SO答案引用了 ...

The ECMAScript Standard defines this as a keyword that "evaluates to the value of the ThisBinding of the current execution context" (§11.1.1). ECMAScript标准将其定义为“评估为当前执行上下文的ThisBinding的值”(第11.1.1节)的关键字。

So if you don't have something attached to an object, window (or whatever your global context is; in a browser, it's window ) is this . 因此,如果您没有在对象, window (或任何全局上下文;在浏览器中是window )上附加任何内容,则为this Unless you use strict mode... But otherwise this is the calling object. 除非您使用严格模式...否则,否则this就是调用对象。 foo.bar() should have foo in this when bar is called, for instance. foo.bar()应该有foothis时候bar被调用,例如。

You can use the functions call and apply to explicitly set the context that's in this when calling a function. 您可以使用函数call ,并apply于明确地设置这是在上下文this调用函数时。 But that's all explained in detail at those links. 但这一切都在那些链接中进行了详细说明。

One OO solution 一种面向对象的解决方案

For how to use OO, I'd probably do something like... 对于如何使用OO,我可能会做类似...

function Cmd(helpInfo, executableFunctions) {
    var functionName;

    // Note that we're no longer redefining the cookies function
    // with every call of cmd.help, for instance.
    this.help = function (helpTopic) {
        if (undefined === helpTopic) {
            console.log('General help text');
        } else if (helpInfo.hasOwnProperty(helpTopic)) {
            console.log(helpInfo[helpTopic]);
        } else {
            console.log('Requested topic not found');
        }
    };

    for (functionName in executableFunctions)
    {
        if (executableFunctions.hasOwnProperty(functionName))
        {
            this[functionName] = executableFunctions[functionName];
        }
    }
}

// Set up initialization info for your new command object.
var helpInfoCooking = {
    cookies: "Cookies recipe",
    brownies: "Brownies recipe",
    cake: "Cake receipe"
};

var executableFunctions = {
    invite: function(id) {
        //send_PRIVGRP_INVITE(id);
        console.log("send_PRIVGRP_INVITE(" + id + ");");
    },
    say: function(message) {
        console.log("you'd probably say \"" + message + "\" somehow");
    }
};

// Create an instance of Cmd.
var cmd = new Cmd(helpInfoCooking, executableFunctions);

cmd.help();
cmd.help("cookies");
cmd.help("milk");
cmd.help("cake");
cmd.invite("wack");
cmd.help("invite");

cmd.say("This is a message");

Results: 结果:

General help text
Cookies recipe
Requested topic not found
Cake receipe
send_PRIVGRP_INVITE(wack);
Requested topic not found
you'd probably say "This is a message" somehow

YMMV, etc. Maybe overkill if you're doing a singleton setup, but it wouldn't be that hard to rearrange into a real singleton setup either. YMMV,等等。如果您正在执行单例设置,则可能会过大,但也可以很容易地将其重新排列为真正的单例设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM