当提供函数名称时,检查函数是否存在于同一作用域中

Checking if function exist in same scope when supplied the function name

本文关键字:函数 存在 是否 于同一 检查 作用域      更新时间:2023-09-26

我有这个format原型方法(简化),我想做的是检查char是否是字母(不区分大小写),它是否也是在相同范围内声明的函数。如果是,我想调用函数。因此,如果我传入x,它应该执行警报。

我将使用这个方法通过给定的格式字符串来格式化日期。例如format('H:i:s'),它将检查H、i和s是否是一个函数并调用它们。

如何做到这一点?

我尝试了一些基于这个答案的东西:https://stackoverflow.com/a/359910/1115367

这是我的代码:

function Time() {
    //initialization
}
Time.prototype = {
    format: function (char) {
        if (char.test(/[a-z]/i) && typeof window[char] === 'function') { //undefined
           window[char]();
        }
        function x() {
            alert('works');
        }
    }
};

如果我传入一个值,它会返回:Uncaught TypeError:undefined不是函数

没有办法按名称检索局部变量(或函数)(据我所知)。

声明的命名函数被分配给一个同名变量:function thing(){}~var thing = function(){}

全局变量会自动附加到window,因此您可以使用window对象按名称检索它们。

然而,(幸运的是)并非所有其他变量都是如此。

例如

var global1 = 'thing'; // root level (no wrapping function) -> global
(function(){
    global2 = 'global';     // no 'var' keyword -> global variable (bad practice and not accepted in strict mode)
    var local = 'whatever'; // local variable
    function check(name){
        if(window[name]) console.log('found: '+ name);
        else console.log('nope: '+name);
    }
    check('foo');
    check('global1');
    check('global2');
    check('local');
}());

将输出:

[Log] nope: foo
[Log] found: global1
[Log] found: global2
[Log] nope: local

但是,您可以做的是将方法附加到对象上。

编辑

如果它是一个选项,您也可以直接将函数作为参数传递(而不是包含其名称的字符串)。

function a(){}
function toCall(f){
   // do stuff with f
}
toCall(a);

test()不是字符串的函数,它是RegExp的函数。请参阅此处的test文档:RegExp.protype.test()

因此,首先创建一个RegExp对象,然后使用它来调用test,传入您的字符串char

在仔细查看了您的代码之后,我认为您需要将格式化函数转换为"类"(JavaScript实际上没有类,但您可以从函数创建对象)。

function Formatter() {
    this.format = function(char) {
        var regex = /[a-z]/i;
        if (regex.test(char) && typeof this[char] === 'function') {
           this[char]();
        }
    };
    this.x = function() {
        alert('works');
    }
}
var formatter = new Formatter();
formatter.format('x');

这是正在工作的小提琴。

正如您所看到的,您创建了一个格式化程序对象,其中包含format函数和其作用域this中的x函数。

您可以使用立即调用函数表达式(IIFE)来创建您的作用域:

var Time = (function() {
  var handlers = {
    x: function () {
      console.log('x invoked');
    }
  };
  function Time() {
    // fun stuff
  }
  Time.prototype = {
    format: function(char) {
      handlers[char](); // if char === 'x'
    }
  };
  return Time;
}());