Javascript 获取原型对象的名称

Javascript 获取原型对象的名称,javascript,knockout.js,prototype,Javascript,Knockout.js,Prototype,这个问题刚刚被升级,所以可以用我所做的更新问题 我通过迭代窗口对象(或用户指定的对象根)来解决这个问题,当我找到正确的实例时,我回溯并从索引中获得名称。最终的解决方案可以在这里找到 更新结束 我计划为KnockoutJS/MVC编写一个配置模板源引擎约定。 我从一个小小的客户端POC开始,马上就遇到了一个节目主持人 我的计划是使用这种语法或类似的东西 MyApp.EditCustomersViewModel = function() { ko.templates.loadView(thi

这个问题刚刚被升级,所以可以用我所做的更新问题

我通过迭代窗口对象(或用户指定的对象根)来解决这个问题,当我找到正确的实例时,我回溯并从索引中获得名称。最终的解决方案可以在这里找到

更新结束

我计划为KnockoutJS/MVC编写一个配置模板源引擎约定。 我从一个小小的客户端POC开始,马上就遇到了一个节目主持人

我的计划是使用这种语法或类似的东西

MyApp.EditCustomersViewModel = function() {
   ko.templates.loadView(this);
};
执行此操作时,它将检查tamplate缓存或使用对象名作为键从服务器获取模板。 问题是我无法得到原型对象的名称,我尝试了这个

Object.prototype.getName = function() {
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};
If适用于这样定义的对象

function MyClass() { 
}
MyApp = {};
MyApp.MyClass = function() {
};
如果您将原型添加到上述对象中,它将不起作用,或者如果您这样定义它

function MyClass() { 
}
MyApp = {};
MyApp.MyClass = function() {
};
原型和范围界定是两个必须的,所以这是一个展示的障碍,有什么想法吗

小提琴:

编辑:背景如下

在服务器上,您有这样的结构

  • 模板\[ViewName]\index.html
  • 模板\[ViewName]\sub-model-template.html
在客户机上,您将执行以下操作

MyApp.EditCustomersViewModel = function() {
   ko.templates.loadView(this);
};

它将生成一个以对象名称为键的ajax请求,该请求将获取相关视图的所有模板

您可以使用命名函数表达式

MyApp.MyClass = function MyClass() { ... };
但请注意(令人惊讶的是)它们并不是在所有版本的IE中都能正常工作

请参阅:

这并不能回答问题 但是,代码可能对其他人有用,因此我将其留在这里,以防万一。我不希望有人投赞成票,但也请不要滥用它来投反对票。谢谢


我不知道你的用例,因此我认为你有一个设计问题——你描述的问题在实践中不应该发生

但假设你确实需要让它工作。做你需要的事情的简单方法如下:

function findNamed(obj, fn){
    for(var p in obj)
        if(obj[p] === fn)
            return p;
    return false;
}

var m = {};
m.MyClass = function() {};

console.log(findNamed(m, m.MyClass));
当然,可以将解决方案制作成更合适的OOP形式,但这只是给出一个想法

要复制您的用例,它将如下所示:

m.MyClass = function() {
    findNamed(this, arguments.callee);
};

因此,最后的代码是:

Object.prototype.getNameOfCall = function(fn) {
    for(var p in this)
        if(this[p] === fn)
            return p;
    throw "Callback not in object.";
};

var m = {};
m.MyClass = function() {
    console.log(this.getNameOfCall(arguments.callee)); // MyClass
};

m.MyClass(); // test it out

我认为您在不正确地替换函数原型时遇到了问题:如果您替换了函数原型对象,那么您必须在原型中保留
构造函数
成员:

function Test1() {
}
Test1.prototype={
  constructor: Test1
};

MyApp={};
MyApp.MyClass=function MyClass(){
};
MyApp.MyClass.prototype={
  constructor: MyApp.MyClass
};
你的例子是:

修改的示例:

只有提升的函数(
函数someFunc(){
)具有可检索的名称

分配的函数不会,因为从技术上讲,您不是在命名函数,而是在创建一个匿名函数,并将对它的引用(在内存中)分配给一个命名变量

因此,命名的是var,而不是函数

这使得检索函数名的想法几乎成为一个无起点的想法,因为在任何模糊成熟的模式中,您将编写方法,而不是提升的函数——当然,方法是分配的函数

命名表达式(见其他答案)是一个局部解决方案,但它们还有其他问题——尤其是在旧IE中缺乏支持


(旁注:我一直希望浏览器供应商能够围绕这个问题进行构建,这样分配函数的名称就可以检索,但现在还没有乐趣。)

只提升函数(
function someFunc()
)有一个可检索的名称。分配的函数没有,因为从技术上讲,您不是在命名函数,而是在创建一个匿名函数并分配对它的引用(在内存中)到一个命名的变量。所以命名的是变量,而不是函数。我一直希望浏览器供应商围绕这一点进行构建,这样分配的函数的名称就可以检索,但现在还没有乐趣。你有什么理由需要得到具体的名称,而不是对象本身吗?不:/是的,我需要这个名称是因为framework我计划创建的对象将获取一个对象,然后使用该对象的名称向服务器请求淘汰模板。@Utkanos如果您在答案中添加注释,那么我可以将其标记为答案,谢谢…但在DevTools控制台中,使用new创建的对象将显示构造函数的名称???我不怪IE…。这非常模糊。考虑到der:
window['test']=function test(){};
请详细说明,我不明白你的意思,我将在接下来的几天中编辑我的问题,并详细说明我为什么要这样做minutes@Anders现在看一下,特别是最后一个代码块(顺便说一下,它可以在web浏览器控制台中测试).刚刚发布,我不能从构造函数中调用它,我不需要从模型加载器帮助类中执行,您的解决方案需要从您想要名称的对象的构造函数中调用它。我当然可以解决它,我猜您可以从构造函数外以某种方式使用它吗?谢谢,您完全没有理解q这是关于prototype declarion的,你只需要调用一个方法..你需要做新的m.MyClass(),这会破坏你的代码,对不起,我想写一个不同的答案,但我认为这个答案涵盖得很好。当你做
class.prototype={};
,您明确地清除了原型。这一点应该很明显,当您用其他变量替换变量时,除非您像Andrew一样跟踪它,否则无法找到以前存在的变量。我认为这应该可以很好地解决这个问题。+1命名表达式确实适用于原型,但在IE类w中我将是全局的,它可能会引入错误以及缩小脚本等问题。在我的情况下,我不能依赖用户使用了命名表达式declaretion,因此我不能使用类名作为键,很遗憾:/