获取原型对象的名称
Get name of prototype object
这个问题刚刚获得投票,所以可以用我所做的更新问题
我通过迭代窗口对象(或用户指定的对象根)来解决它,当我找到正确的实例时,我回溯并从索引中获得名称。最终解决方案可以在这里找到
https://github.com/AndersMalmgren/Knockout.BindingConventions
更新结束
我正计划为KnockoutJS/MVC编写一个关于配置模板源引擎的约定。我刚开始做一个小客户端的POC,然后马上遇到了一个阻止表演的
我的计划是使用这种语法或类似的
MyApp.EditCustomersViewModel = function() {
ko.templates.loadView(this);
};
当这样做时,它将检查模板缓存或使用对象名称作为密钥从服务器获取模板。问题是我无法获得原型对象的名称,我尝试了这个
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() {
};
原型和范围界定是两个必须的,所以这是一个展示,有什么想法吗?
Fiddle:http://jsfiddle.net/aRWLA/
编辑:它的背景是这样的。
在服务器上,你有这样的结构
- 模板''[ViewName]''index.html
- Templates''[ViewName]''sub-moodel-template.html
在客户端上,您将执行
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/
这并不能回答问题
然而,代码可能对其他人有用,所以我把它留在这里,以防万一。我不期待赞成票,但也请不要滥用它来反对票。谢谢
我不知道你的用例,因此我认为你有一个设计问题——你描述的问题不应该在实践中发生。
但假设你确实需要让它发挥作用。做你需要的事情的一个简单方法是:
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
- 重载JS'firefox中的对象原型
- 带有对象/原型的链式承诺(Q延期)
- 别名或以其他方式合并两个具有不同名称的相同对象原型
- 创建后指定对象原型
- javascript对象原型与jquery冲突
- 为什么我要将函数添加到对象原型中,而不是将其添加到对象中
- 基本对象/原型语法问题
- Javascript对象/原型.我的理解错了吗
- ES6 const,用于在JavaScript中创建对象原型;这是一种模式吗
- 在角度表达式中使用对象原型
- 对象原型和继承
- 为什么javascript对象原型被称为“fn”
- Uncaught TypeError:对象原型在Symfony 2中只能是Object或ExtJS为null
- 在Javascript中将对象原型函数绑定到对象
- 对象原型在Canvas Game中不起作用
- 如何获取Javascript对象原型的属性
- 为对象原型提供一个方法,该方法指向对象自身属性的值
- 向对象原型添加命名空间方法
- 在Vanilla Javascript中使用窗体中的对象原型创建多个用户
- Javascript对象原型错误