调试JavaScript(骨干网和木偶) [英] Debugging Javascript (Backbone and Marionette)

查看:92
本文介绍了调试JavaScript(骨干网和木偶)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在,当我使用的是Chrome浏览器开发工具,调试骨干或提线木偶,我结束了设置断点和诸如此类的东西,但一旦code停顿,它很难说我的工作是什么类型的对象由于Chrome标签的一切子。结果
(我想是因为这是构造函数)

Right now, while I am debugging backbone or marionette using the chrome dev tools, I end up setting break points and whatnot, but once the code pauses, its hard to tell what type of objects i'm working with because chrome labels everything a "child".
(I think because that's the constructor function)

有没有简单的方法要么改变这一声明或决定我使用的模型/收藏类型。

Is there any easy way to either change this declaration or determine which type of model/collection i'm using.

量疯狂这将导致我要开始做这样的事情:

The amount craziness this causes in me wants to start doing something like this:

MyModel = Backbone.Model.Extend({
    // the $$$ puts it at the top of the inspector, the NAME is just for other devs
    $$$NAME = "MyModel",  
    ...
});

我真的不喜欢它,因为它的...丑陋,它的一个变量...它不仅有助于当我检查和扩展该变量...这将是巨大的,将名称更改Chrome浏览器用于显示它。

I don't really like it, because its... ugly, its a variable... and it only helps when I inspect and expand the variable... it would be great to change the name chrome uses to display it.

在任何情况下,没有人知道如何更改名称?或者你有使用其他清洁约定?

In any case, does anyone know how to change the name? or have some other cleaner convention you use?

谢谢!

推荐答案

背景

有趣的是,看看为什么浏览器使用儿童在控制台/调试器显示骨干对象的类型。

It is interesting to look at why the browser uses "child" to display the type of Backbone objects in the console / debugger.

所有的JavaScript对象都有一个constructor属性,用来创建对象的函数的引用。构造函数所使用的浏览器显示在控制台/调试对象的类型。如果它不是空将使用构造函数的名称属性的值。然而,只有使用命名功能前pressions得到一个有用的name属性定义的功能:

All JavaScript objects have a constructor property, a reference to the function used to create the object. The constructor is used by the browser to display the object’s "type" in the console / debugger. The value of the constructor function’s name property will be used if it is not empty. However, only functions defined using named function expressions get a useful name property:

function A() {  }
console.log(A.name); // 'A' 

匿名函数有一个空的name属性:

Anonymous functions have an empty name property:

var B = function() {  };
console.log(B.name); // ''

那么,什么用匿名函数发生什么呢?铬推断匿名函数的名字来自于这是第一次分配的功能变量或属性的名称。下面是一些例子:

So, what happens with anonymous functions? Chrome infers the name of anonymous functions from the name of the variable or property to which the function was first assigned. Here are some examples:

// 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() { … }
};

一个更详细的脚本可以在这里找到: http://jsfiddle.net/danmalcolm/Xa7ma/6/

A more detailed script is available here: http://jsfiddle.net/danmalcolm/Xa7ma/6/

浏览器似乎从源头code得到这个名字 - 没有一个JavaScript功能,可以在运行时告诉你的第一个变量的一个函数被分配到的名称。其他浏览器支持在使用匿名构造函数中定义的DisplayName属性的公约,但这并不目前在Chrome中发生:<一href=\"http://$c$c.google.com/p/chromium/issues/detail?id=17356\">http://$c$c.google.com/p/chromium/issues/detail?id=17356.

The browser appears to get this name from the source code - there isn’t a JavaScript feature that can tell you at runtime the name of the first variable that a function was assigned to. Other browsers support a convention where a displayName property defined on anonymous constructor functions is used, but this doesn’t currently happen in Chrome: http://code.google.com/p/chromium/issues/detail?id=17356.

回到主干,你不使用自定义构造函数(见下文)假设,你的类型将最终获得一个匿名构造函数中的骨干的扩展功能的使用模型,视图,收集和路线如下:

Returning to Backbone, assuming you're not using a custom constructor (see below), your type will end up with an anonymous constructor function, created in Backbone's extend function used by Model, View, Collection and Route as follows:

child = function(){ return parent.apply(this, arguments); };

这就是为什么你在控制台/调试器看到子旁边的骨干对象。这是在为你的对象构造一个合适的名称浏览器的最佳猜测。

This is why you see "child" next to your Backbone objects in the console / debugger. It is the browser’s best guess at a suitable name for your object’s constructor.

解决方案

为了让你的对象更好的类型名称,您可以通过第一个protoProps的说法,当你定义你的主干类型提供一个名为构造函数。只需添加一个封装调用父的构造函数的构造属性,如下所示:

To give your objects a better type name, you can supply a named constructor via the first "protoProps" argument when you define your Backbone types. Just add a constructor property that wraps a call to the "parent" constructor as follows:

var Product = Backbone.Model.extend({
    constructor: function Product() {
        Backbone.Model.prototype.constructor.apply(this, arguments);
    }
});

您的产品模型实例现在看的真正的不错的调试器。

Your Product model instances will now look really nice in the debugger.

这是一个有点麻烦,为每个View做到这一点,模型,收集和路由定义。你可以猴子补丁骨干网的扩展功能做的工作适合你。

It is a bit cumbersome to do this for every View, Model, Collection and Route that you define. You can monkey patch Backbone’s extend function to do the work for you.

您首先需要建立一个约定定义你的类型的名称。这里,我们使用一个 __ __名属性,该属性指定如下:

You first need to establish a convention for defining the names of your types. Here we're using a __name__ property, which you specify as follows:

var Product = Backbone.Model.extend({
    __name__: 'Product'
    // other props
});

您再更换所使用的模型,视图,收集和路线读取此属性和一个名为构造函数添加到您的类型扩展功能。你并不需要修改Backbone.js的本身,就包括被Backbone.js的加载后单独的脚本如下。

You then replace the extend function used by Model, View, Collection and Route to read this property and add a named constructor to your type. You don’t need to modify backbone.js itself, just include the following in a separate script that is loaded after 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;
})();

这篇关于调试JavaScript(骨干网和木偶)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆