Mat*_*tyP 14 javascript google-chrome-devtools backbone.js marionette
现在,而我使用的是Chrome浏览器开发工具,调试骨干或提线木偶,我最终设置断点和诸如此类的东西,但一旦代码暂停,其很难说哪种类型的我和由于Chrome标签一切工作的对象"儿童".
(我想因为那是构造函数)
是否有任何简单的方法来更改此声明或确定我正在使用的模型/集合类型.
这导致我的疯狂欲望开始做这样的事情:
MyModel = Backbone.Model.Extend({
// the $$$ puts it at the top of the inspector, the NAME is just for other devs
$$$NAME = "MyModel",
...
});
Run Code Online (Sandbox Code Playgroud)
我真的不喜欢它,因为它......丑陋,它是一个变量......它只有在我检查和扩展变量时才有用......更改名称chrome用来显示它会很棒.
无论如何,有谁知道如何更改名称?或者你使用其他一些清洁惯例?
谢谢!
马特
Dan*_*olm 33
背景
有趣的是,为什么浏览器使用"child"来显示控制台/调试器中的Backbone对象的类型.
所有JavaScript对象都有一个构造函数属性,即对用于创建对象的函数的引用.浏览器使用构造函数在控制台/调试器中显示对象的"类型".如果构造函数的name属性不为空,则将使用它的值.但是,只有使用命名函数表达式定义的函数才能获得有用的name属性:
function A() { }
console.log(A.name); // 'A'
Run Code Online (Sandbox Code Playgroud)
匿名函数具有空名称属性:
var B = function() { };
console.log(B.name); // ''
Run Code Online (Sandbox Code Playgroud)
那么,匿名函数会发生什么?Chrome从首次分配函数的变量或属性的名称中推断出匿名函数的名称.这里有些例子:
// 1. named function expression - objects will show as “a” in the console
function a() { … }
// 2. anonymous function assigned to variable - objects will show as “b” in the console
var b = function(){ … };
// 3. anonymous function assigned to property of object - objects will show as “container.c” in the debugger
var container = {
c: function() { … }
};
Run Code Online (Sandbox Code Playgroud)
这里有一个更详细的脚本:http://jsfiddle.net/danmalcolm/Xa7ma/6/
浏览器似乎从源代码中获取此名称 - 没有JavaScript功能可以在运行时告诉您功能分配给的第一个变量的名称.其他浏览器支持使用匿名构造函数定义的displayName属性的约定,但目前在Chrome中不会发生这种情况:http://code.google.com/p/chromium/issues/detail?id = 17356.
回到Backbone,假设你没有使用自定义构造函数(见下文),你的类型将最终得到一个匿名构造函数,在Backbone的模型,视图,集合和路由使用的扩展函数中创建,如下所示:
child = function(){ return parent.apply(this, arguments); };
Run Code Online (Sandbox Code Playgroud)
这就是您在控制台/调试器中看到Backbone对象旁边的"child"的原因.这是浏览器对对象构造函数的合适名称的最佳猜测.
解决方案
为了给对象提供更好的类型名称,在定义Backbone类型时,可以通过第一个"protoProps"参数提供命名构造函数.只需添加一个构造函数属性,该属性包含对"父"构造函数的调用,如下所示:
var Product = Backbone.Model.extend({
constructor: function Product() {
Backbone.Model.prototype.constructor.apply(this, arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
您的产品模型实例现在在调试器中看起来非常好.
对于您定义的每个视图,模型,集合和路由,执行此操作有点麻烦.您可以通过猴子补丁Backbone的扩展功能为您完成工作.
首先需要建立一个约定来定义类型的名称.这里我们使用的__name__属性如下所示:
var Product = Backbone.Model.extend({
__name__: 'Product'
// other props
});
Run Code Online (Sandbox Code Playgroud)
然后,您可以替换Model,View,Collection和Route使用的extend函数来读取此属性,并为您的类型添加命名构造函数.您不需要修改backbone.js本身,只需在backbone.js之后加载的单独脚本中包含以下内容即可.
(function () {
function createNamedConstructor(name, constructor) {
var fn = new Function('constructor', 'return function ' + name + '()\n'
+ '{\n'
+ ' // wrapper function created dynamically for "' + name + '" constructor to allow instances to be identified in the debugger\n'
+ ' constructor.apply(this, arguments);\n'
+ '};');
return fn(constructor);
}
var originalExtend = Backbone.View.extend; // Model, Collection, Router and View shared the same extend function
var nameProp = '__name__';
var newExtend = function (protoProps, classProps) {
if (protoProps && protoProps.hasOwnProperty(nameProp)) {
// TODO - check that name is a valid identifier
var name = protoProps[nameProp];
// wrap constructor from protoProps if supplied or 'this' (the function we are extending)
var constructor = protoProps.hasOwnProperty('constructor') ? protoProps.constructor : this;
protoProps = _.extend(protoProps, {
constructor: createNamedConstructor(name, constructor)
});
}
return originalExtend.call(this, protoProps, classProps);
};
Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = newExtend;
})();
Run Code Online (Sandbox Code Playgroud)