[英]Get name of prototype object
这个问题刚刚起来,所以可以用我所做的更新问题
我通过遍历窗口对象(或用户指定的对象root)来解决它,当我找到正确的实例时,我回溯并从索引中获取名称。 最终的解决方案可以在这里找到
https://github.com/AndersMalmgren/Knockout.BindingConventions
更新结束
我打算为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] : "";
};
如果适用于这样定义的对象
function MyClass() {
}
如果您将原型添加到上面的对象,它将无法工作,或者如果您这样定义它
MyApp = {};
MyApp.MyClass = function() {
};
原型和范围是两个必须,所以这是一个showstopper,任何想法?
小提琴: http : //jsfiddle.net/aRWLA/
编辑:这个的背景是这样的。
在服务器上,你有这样的结构
在客户端你会做
MyApp.EditCustomersViewModel = function() {
ko.templates.loadView(this);
};
这将生成一个以对象名称为键的ajax请求,该请求将获取相关视图的所有模板
只有提升的函数( function someFunc() {
)具有可检索的名称。
分配的函数没有,因为你在技术上并没有命名函数,而是创建一个匿名函数并将它(在内存中)的引用分配给一个命名变量。
所以它是var,而不是函数,它被命名。
这使得检索函数名称的想法几乎不可能,因为在任何模糊成熟的模式中,您将编写方法,而不是提升函数 - 当然,方法也是分配函数。
命名表达式(参见其他答案)是部分解决方法,但这些还有其他问题 - 尤其是旧IE中缺少支持。
(旁注:我一直希望浏览器厂商能够围绕这一点进行构建,以便分配的功能的名称变得可检索,但AFAIK还没有快乐。)
我认为你在替换函数原型时有问题:如果你替换函数原型对象那么你必须保留原型中的constructor
成员:
function Test1() {
}
Test1.prototype={
constructor: Test1
};
MyApp={};
MyApp.MyClass=function MyClass(){
};
MyApp.MyClass.prototype={
constructor: MyApp.MyClass
};
你的例子: http : //jsfiddle.net/aRWLA/1/
修改示例: http : //jsfiddle.net/aRWLA/2/
您可以使用命名函数表达式 :
MyApp.MyClass = function MyClass() { ... };
但请注意(惊讶)它们在所有版本的IE中都无法正常工作。
请参阅: http : //kangax.github.com/nfe/
但是,代码可能对其他人有用,所以我将它留在这里,以防万一。 我不指望upvotes,但请不要滥用它进行downvoting。 谢谢。
我不知道你的用例,因此我认为你有一个设计问题 - 你描述的问题不应该在实践中发生。
但是,让我们说你确实需要这个工作。 一个简单的方法来做你需要的东西是这样的:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.