鉴于Backbone模型的一个实例,我怎么知道这个实例的“类”(可以这么说)?
例如:
class Car extends Backbone.Model
mycar = new Car()
我需要的是:
mycar.modelName # => 'Car'
答案 0 :(得分:23)
我尝试了Mitch的建议,但在Chrome中,对我来说,model.constructor.name总是""
。
我选择使用约定。我现在使用extend的第二个参数创建一个类属性,其工作方式如下:
directory.models.SomeModel = Backbone.Model.extend({
// usual model instance stuff
}, {
modelType: "SomeModel" // class property
});
我发现我总能得到我想要的东西:
var mt = model.constructor.modelType;
答案 1 :(得分:14)
在撰写本文时,您可以通过执行以下操作获取模型的类名:
model.constructor.name
这适用于Chrome浏览器。
答案 2 :(得分:10)
我认为这一般存在问题。我打算提出一些这里提到的选项(How do I get the name of an object's type in JavaScript?),但我遇到了第一个选项的问题。您可以随时扩展所有模型,使其具有返回模型“名称”的功能,但我可以理解为什么您可能会发现不太满意。
答案 3 :(得分:0)
除了IE之外,所有浏览器都已经解决了这个问题,但是很容易进行填充。答案是Function.name
:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
绝对利用这一点!在ES6类中,构造函数的Function.name是类名,因此在ES6中:
class Car { /*...*/ }
var c = new Car();
console.log(c.constructor.name); // "Car"
在当前的ES5中,并非所有库都利用了这一点。例如,Backbone没有。 :( Backbone构造函数是匿名函数,所以
var m = new Backbone.Model();
console.log(m.constructor.name); // "undefined" :(
不幸。和其他人一样,如果您使用Backbone,您必须制作自己的命名系统。
这是一个用于Function.name:
的polyfill// Polyfill for Function.name on browsers that do not support it (IE):
// See: http://stackoverflow.com/questions/6903762/function-name-not-supported-in-ie
if (!(function f() {}).name) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var name = this.toString().match(/^\s*function\s*(\S*)\s*\(/)[1];
// For better performance only parse once, and then cache the
// result through a new accessor for repeated access.
Object.defineProperty(this, 'name', { value: name });
return name;
}
});
}
答案 4 :(得分:0)
您可以查询对象实例的继承树(也称为原型链),如下所示:
对象.__原__.__原__.__原__
您可以看到可用的内容。您必须手动将任何类型名称属性添加到每个视图和/或模型。这是最干净的方法。我推荐这个。只需在每个视图和/或模型中添加'className:“MyCompany.MyProject.MyArea.MyView”即可。
如果你没有为你的对象添加一个className属性,那么仍有一种方法可以获得它(例如用于调试输出):
假设您执行以下操作:“MyCompany.MyProject.MyArea.MyView = Backbone.View.extend({”视图/模型类名称位于全局命名空间var名称中。从对象实例中我们无法访问该全局变量虽然不是很理想,但我们能做的最好的事情是遍历命名空间寻找var:
function findBackboneClassName(ns, object, prefix, depth) {
prefix = typeof prefix !== 'undefined' ? prefix : "";
depth = typeof depth !== 'undefined' ? depth : 0;
if (depth > 5) return null;
for (i in ns) {
try { ns[i]; } catch (e) { continue; }
if (/top|window|document|parent|frames|self|chrome|form|theForm/.test(i)) continue;
//console.log(">" + prefix + "." + i + " " + typeof(ns[i]));
if (ns[i] == object.constructor) {
//console.log("Found:", prefix + "." + i);
return prefix + "." + i;
}
if (typeof (ns[i]) == "object") {
var r = findBackboneClassName(ns[i], object, prefix + (prefix != "" ? "." : "") + i, depth + 1);
if (r != null) return r;
}
}
return null;
}
findBackboneClassName(window, myBackboneViewInstance);
理想情况下,您为“window”以外的类型使用命名空间。这使得它更干净,更容易遍历。您只需将“窗口”替换为命名空间的基础,并在需要正确添加前缀时传入所需的前缀。你也可以删除一些像try..catch和if..continue。
这样的行findBackboneClassName(MyCompany.MyProject, myBackboneViewInstance, "MyCompany.MyProject");
从objectInstance.constructor获取类名的技巧因为它继承的方式而不适用于主干。所有ctors对我来说都是一样的:“function(){return parent.apply(this,arguments);}”。