zoukankan      html  css  js  c++  java
  • Notes on Paul Irish's "Things I learned from the jQuery source" casts

    I watched these videos on 2012/12/14. Today's jQuery version is 1.8.3. So there might be some differences from the original video. I've briefly noted some of the differences between what described in the video and the current stable release. Most code he desribed can be found easily in speed/jquery-basic.js (1.4.2).

    Episode 1

    Anonymous Function

    1:16

    window object passed into anonymous function, for faster object accessing.
    变成局部变量,为什么可以更快访问?也许是保存变量的地方不同。
    c中,全局变量保存在全局/静态存储区。
    而局部变量保存在栈中。
    undefined as last parameter, to restore the potential overriden undefined object (e.g. undefined=true "a**hole effect").

    (function(window, undefined) {
      // do stuff here
    })(window);
    

    Asynchronous Recursion

    7:45

    setInterval may not work at the time you expected, when the action takes longer than the time you specified.
    跟我理解的一样,主要就是在事件执行时间超过interval的时候会出问题

    (function() {
      doStuff();
    
     // gonna wait doStuff done then
      setTimeout(arguments.callee, 100);
    })();
    

    arguments.callee deprecated in ES5 strict mode.

    We can use named function:

    (function loopback() {
      doStuff();
    
      // gonna wait doStuff done then
      setTimeout(loopback, 100);
    })();
    

    noconflict()

    12:34

    (didn't get it)

    jQuery.props

    14:15

    This is a bridge for class (DOM: className) and for (DOM: htmlFor), and some downcased-to-camelCase mappings (!)

    jQuery.props.dt = "data-type";
    $("#something").attr("dt"); // gets its data-type attribute
    

    jQuery.fx.speeds

    18:01

    "Constant" variable to define animation speed (e.g. fast / slow). jQuery searches values in this object. If not found, it uses _default value.

    jQuery.fx.speeds.kilo = 1024; // define a new speed with 1024ms duration
    $("#somethings").fadeIn("kilo");
    

    DOM Ready callback

    21:21

    In jQuery 1.4.x, DOM Ready callback is implemented in jQuery.bindReady. However this function does not exist in 1.8.3 (current stable release). The most similar function is jQuery.ready.promise.

    Implemenation details:

    If DOMContentLoaded event is supported, use it.
    If document.attachEvent exists (old IEs), use it to listen to onreadystatechange event
    Otherwise, use doScrollCheck, keeps trying scrolling the document (1ms), until it does not raise exception, then it's ready.
    See also:

    IEContentLoaded - An alternative for DOMContenloaded on Internet Explorer
    src/core.js#L828 (jQuery.ready.promise)

    home-made getScript()

    24:41

    Outdated. He extracted $.getScript implementation of jQuery 1.4.1. Today's jQuery uses XMLHttpRequest.

    The 1.4.x implementation can be found at speed/jquery-basic.js#L5060

    Selector Performance

    33:23

    (may be outdated. See sizzle.js)

    In 1.4.x,

    $("#id").find("tag.thing")
    is faster than

    $("#id tag.thing")
    because the latter must traverse the tree in JavaScript level instead of DOM level.

    Todays' jQuery is Sizzle-driven and may already utilies this shortcut too.

    :password is slower than input:password, because the former does traverse through all the possible tags.

    jQuery.parseJSON

    38:46

    jQuery use native parser (window.JSON.parse) if supported.

    Otherwise, make a new function and invoke it:

    (new Function("return "+ jsonSrc ))();
    Note the capital F (not function): it makes a new function object, with source code in the parameter.

    Since JSON is the literal representation of a JavaScript Object, the browser can parse the object literal inside the function, and turns it into a real object.

    jQuery will check if the string is a real JSON string, otherwise it prints an error message to the console.

    See also:

    Function - JavaScript | MDN
    src/core.js#L490

    jQuery.unique()

    42:15

    It uses Sizzle.uniqueSort (same as today's implementation in 1.8.3).

    The official document says that it does work for any array element other than DOM Element. It is still documented as "unspported" in today's 1.8.3.

    Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.
    However I've tried non-DOM element scalars in 1.8.3, and it does work for Number, String and true, but not work for null, false and undefined. Objects (non-scalar) with same properties are all kept, duplications are not removed. Though this behavior makes sense, because two individual objects are compared by object address, not its properties.

    Example

    [tl;dr] $.unique doesn't guarantee correct result if there are items not DOM Element. So do use it for an array containing DOM elements only.

    DOM elements:

    div = document.createElement("div");
    div.innerHTML = '<span class="a"></span><span class="b"></span><span class="c">'
    "<span class="a"></span><span class="b"></span><span class="c">"
    
    ar1 = $(div).find("span").get();
    //=> [<span class="a"></span><span class="b"></span>,<span class="c"></span>]
    
    ar1.concat($(div).find("span").get());
    //=> [<span class="a"></span><span class="b"></span>,<span class="c"></span>,<span class="a"></span><span class="b"></span>,<span class="c"></span>]
    
    jQuery.unique(ar1)
    //=> [<span class="a"></span><span class="b"></span>,<span class="c"></span>]
    

    Now let's see scalar values:

    var arr;
    
    // Number, true, String works
    arr = [1, 2, true, "hi", 3, 3, true, 2, 1, "hi"];
    $.unique(arr);
    // => [3, "hi", true, 2, 1]
    
    // false and undefined doesn't work
    arr = [false, false, undefined, undefined];
    $.unique(arr);
    // => [false, false, undefined, undefined]
    
    // null doesn't work, and will raise exception if the array contains anything other than null:
    arr = [null, null];
    $.unique(arr);
    // => [null, null]
    
    arr = [null, null, false];
    $.unique(arr);
    // => TypeError: Cannot read property 'compareDocumentPosition' of null
    
    // Object literals doens't work either, since they're allocated in different memory spaces
    arr = [{a:1, b:2}, {a:1, b:2}];
    JSON.stringify($.unique(arr));
    // => "[{"a":1,"b":2},{"a":1,"b":2}]"
    

    Paul Irish hacked it to make 1.4.1's unique() possible to also deal with non-DOM Element objects, see: How to fulfill your own feature request -or- Duck Punching with jQuery! « Paul Irish

    See also:

    jQuery.unique() – jQuery API
    sizzle/sizzle.js#L994

    delay

    46:58

    In 1.4.1, to delay an animation from starting, this:

    $(elem).delay(2000).fadeOut();
    doesn't work because there is no queue, which delay requires.

    $(elem).queue(function() {
    $(elem).delay(2000).fadeOut();
    });
    this would work.

    I've tried 1.8.3 and it works without .queue wrapping.

    jQuery.support (feature detection)

    48:12

    jQuery.support – jQuery API
    src/support.js

    jQuery Source Modules & Building

    49:53

    jQuery is constructed with many modules. We can build a jQuery with a small set of modules included. The jQuery team said in mid-2012 that there will be a jQuery build tool. It's been 2 years since Paul Irish's cast.

    Nowadays people use jQuery from public CDNs. I think building my own jQuery and deliver it from my server means I cannot leverage public caching for jQuery JavaScript file, and pay delivering fee for it.

    Episode 2

    11 More Things I Learned from the jQuery Source - YouTube
    11 More Things I Learned from the jQuery Source « Paul Irish
    2011/01/19

    jQuery initialization

    1:17

    It initializes in a local variable and then assign back to window.jQuery.

    dom-dynamic-base detection

    (I didn't get it.)

    data-something with JSON / literal

    5:59

    <div data-awesome="true"></div>
    <div data-someobj='{ "best": "jQuery"}'></div>
    

    In the source code it uses ?: conditional tree (bad-smell) to see if the string equals to true, false or null literals and return directly. If none matched, it tries to parse it as JSON. If JSON parsing failed, it returns the original string.

    Technique about getElements

    13:04

    IE detection -- Inserts into a div, and test if a specifc i tag exist.

    This is not how jQuery detects IE, Paul Irish just mentioned a technique used in it.

    div.getElementsByTagName('i')
    

    It actually is a NodeList, and updates lively as div element changes.

    E.g.:

    var ul = document.createElement("ul");
    var items = div.getElementsByTagName("li");
    
    ul.innerHTML += "<li>1</li>";
    console.log(items); //=> [<li>1</li>]
    
    ul.innerHTML += "<li>2</li>";
    console.log(items); //=> [<li>1</li>,<li>2</li>]
    

    Also applies to getElementsByClassName, but does not apply to querySelectorAll.

    jQuery.cssHooks

    18:07

    When getting or setting CSS properties that are unsupported in the browser (e.g. opacity in IE6 or backgroundPositionY in Firefox), jQuery will fallback to browser-specific method according to cssHooks functions.

    See also:

    jQuery.cssHooks – jQuery API
    src/css.js#L497-L640

    .css Auto Vendor-Prefixing

    25:45

    (I rarely use .css because I usually achieve it by Compass and alternating element's className to change the layout.)

    jQuery.fn

    26:53

    jQuery.fn = jQuery.prototype;
    

    This is why we can define a new plug-in by

    jQuery.fn.myPlugin = function() {};
    
  • 相关阅读:
    [转] MapReduce详解
    [转] 自然语言处理全家福:纵览当前NLP中的任务、数据、模型与论文
    [转] 一文读懂BERT中的WordPiece
    [转] 文本分类——GLUE数据集介绍
    [转] Transformer详解
    [python] 转json好用的工具mark
    [转] 深度学习中的注意力机制
    [转] Python之time模块的时间戳、时间字符串格式化与转换
    日期相关
    airflow的定时任务
  • 原文地址:https://www.cnblogs.com/popjohn/p/4474359.html
Copyright © 2011-2022 走看看