2013-04-30 54 views
1

我试图与延伸的jQuery像这样一个插件的工作:

$.extend({ 
    StatelessDeferred: function() { 
     var doneList = $.Callbacks("memory"), 
      promise = { 
      done: doneList.add, 

       // Get a promise for this deferred 
       // If obj is provided, the promise aspect is added to the object 
       promise: function (obj) { 
        var i, 
        keys = ['done', 'promise']; 
        if (obj === undefined) { 
        obj = promise; 
        } else { 
        for (i = 0; i < keys.length; i += 1) { 
         obj[keys[i]] = promise[keys[i]]; 
        } 
        } 
        return obj; 
       } 
      }, 
      deferred = promise.promise({}); 

      deferred.resolveWith = doneList.fireWith; 

     return deferred; 
     } 
    }); 

问题是(我甚至不能确定它的位置造成的),则回调加载后,一个done回调里面,无论是this$(this)是一样的,所以我最终举例为:this === $(this) === $(document)

我不太确定我了解什么被扩展。除了错误的分配外,插件可以正常工作。

问:
能否上述延长是造成this === $(this) === $(document)

编辑: 全部插件(120lines):

"use strict"; 

(function (window, $) { 
    $.extend({ 
     StatelessDeferred: function() { 
     var doneList = $.Callbacks("memory"), 
      promise = { 
      done: doneList.add, 

      // Get a promise for this deferred 
      // If obj is provided, the promise aspect is added to the object 
      promise: function (obj) { 
       var i, 
       keys = ['done', 'promise']; 
       if (obj === undefined) { 
       obj = promise; 
       } else { 
       for (i = 0; i < keys.length; i += 1) { 
        obj[keys[i]] = promise[keys[i]]; 
       } 
       } 
       return obj; 
      } 
      }, 
      deferred = promise.promise({}); 

     deferred.resolveWith = doneList.fireWith; 

     // All done! 
     return deferred; 
     } 
    }); 

    var routes = [], 
    current_priority = 0, 
    methods = { 
     add: function (pattern, priority) { 
     var i = 0, 
      inserted = false, 
      length = routes.length, 
      dfr = $.StatelessDeferred(), 
      context = $(this), 
      escapepattern, 
      matchingpattern; 
     if (priority === undefined) { 
      priority = 0; 
     } 
     if (pattern !== undefined) { 
      // http://simonwillison.net/2006/Jan/20/escape/ 
      escapepattern = pattern.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); 
      matchingpattern = escapepattern 
          .replace(/<int:\w+>/g, "(\\d+)") 
          .replace(/<path:\w+>/g, "(.+)") 
          .replace(/<\w+>/g, "([^/]+)"); 
      while (!inserted) { 
      if ((i === length) || (priority >= routes[i][2])) { 
       routes.splice(i, 0, [new RegExp('^' + matchingpattern + '$'), dfr, priority, context]); 
       inserted = true; 
      } else { 
       i += 1; 
      } 
      } 
     } 
     return dfr.promise(); 
     }, 
     go: function (path, min_priority) { 
     var dfr = $.Deferred(), 
      context = $(this), 
      result; 

     if (min_priority === undefined) { 
      min_priority = 0; 
     } 
     setTimeout(function() { 
      var i = 0, 
      found = false, 
      slice_index = -1, 
      slice_priority = -1; 
      for (i = 0; i < routes.length; i += 1) { 
      if (slice_priority !== routes[i][2]) { 
       slice_priority = routes[i][2]; 
       slice_index = i; 
      } 
      if (routes[i][2] < min_priority) { 
       break; 
      } else if (routes[i][0].test(path)) { 
       result = routes[i][0].exec(path); 
       dfr = routes[i][1]; 
       context = routes[i][3]; 
       current_priority = routes[i][2]; 
       found = true; 
       break; 
      } 
      } 
      if (i === routes.length) { 
      slice_index = i; 
      } 
      if (slice_index > -1) { 
      routes = routes.slice(slice_index); 
      } 
      if (found) { 
      dfr.resolveWith(
       context, 
       result.slice(1) 
      ); 
      } else { 
      dfr.rejectWith(context); 
      } 
     }); 
     return dfr.promise(); 
     }, 
    }; 


    $.routereset = function() { 
    routes = []; 
    current_priority = 0; 
    }; 

    $.routepriority = function() { 
    return current_priority; 
    }; 

    $.fn.route = function (method) { 
    var result; 
    if (methods.hasOwnProperty(method)) { 
     result = methods[method].apply(
     this, 
     Array.prototype.slice.call(arguments, 1) 
    ); 
    } else { 
     $.error('Method ' + method + 
      ' does not exist on jQuery.route'); 
    } 
    return result; 
    }; 

}(window, jQuery)); 

所以我可以用这个作为一个路由器,并设置路径,像这样:

$(".element").add("route", "/foo/bar/<path:params>", 2).done(function(params){ 
    // do something, for example 
    console.log(this); 
    console.log($(this)); 
    console.log("which will be the same = $('.element')); 
}); 

希望它现在更清楚。

谢谢你看看。

+0

'$(this)'不可能是'==='到'$(document)',因为那些对象是函数调用的结果。 – 2013-04-30 16:45:33

+0

让我添加一些代码。 1分钟。 – frequent 2013-04-30 16:46:19

+0

当然。你是否在使用一个可以缓存藏品的插件? – 2013-04-30 16:49:38

回答

0

从文档:

如果只有一个参数被供给到$ .extend(),这意味着该目标参数被删去。在这种情况下,jQuery对象本身被假定为目标。

大多数情况下,jQuery是连接到您的文档具有:$(document).ready()

我认为正在发生的事情是jQuery对象被包裹到文档。然后你将它与$.extend(myObject)合并。这将返回一个既是jQuery对象又是myObject的单个对象。

+2

你能否就这个问题与这个问题相关提供一些解释?谢谢。 – 2013-04-30 16:56:06

+0

hm。我会查的。感谢这个想法 – frequent 2013-04-30 17:06:53

相关问题