191
Dollar Symbol 深淺出 Aaron Huang 1

Dollar symbol

Embed Size (px)

Citation preview

Page 1: Dollar symbol

Dollar Symbol 深⼊入淺出Aaron Huang

1

Page 2: Dollar symbol

Dollar Symbol 深⼊入淺出Aaron Huang

2

只進不出

Page 3: Dollar symbol

Aaron Huang• Sr. F2E @

• F2E Lead @ Faria Systems • Cloud Service Engineer @ Waveface

• Xing “⾏行” - Evernote DevCup 2013 Top 6

Page 4: Dollar symbol

https://jquery.org/history/

• Aug 22, 2005 - John Resig first hints

• Jan 14, 2006 - jQuery announced

• Jan, 2006 - First jQuery Plugin

• Aug, 2006 - v1.0 released

• Jul, 2007 - jQuery UI announced

• Aug, 2008 - jQuery Conference

• Jan, 2009 - Sizzle.js

• Nov, 2011 - jQuery Mobile 1.0

• Jan, 2013 - jQuery 1.9, 2.0-beta, jquery migrate

歷史

Page 5: Dollar symbol

https://jquery.org/history/

• Aug 22, 2005 - John Resig first hints

• Jan 14, 2006 - jQuery announced

• Jan, 2006 - First jQuery Plugin

• Aug, 2006 - v1.0 released

• Jul, 2007 - jQuery UI announced

• Aug, 2008 - jQuery Conference

• Jan, 2009 - Sizzle.js

• Nov, 2011 - jQuery Mobile 1.0

• Jan, 2013 - jQuery 1.9, 2.0-beta, jquery migrate

• April 18, 2013 - jQuery 2.0

• Sep 19, 2013 - jQuery 1.11 and 2.1 Beta 1 Released

歷史

Page 6: Dollar symbol

https://jquery.org/history/

• Jul, 2007 - jQuery UI announced

• Aug, 2008 - jQuery Conference

• Jan, 2009 - Sizzle.js

• Nov, 2011 - jQuery Mobile 1.0

• Jan, 2013 - jQuery 1.9, 2.0-beta, jquery migrate

• April 18, 2013 - jQuery 2.0

• Sep 19, 2013 - jQuery 1.11 and 2.1 Beta 1 Released

Page 7: Dollar symbol

變⾰革

Page 8: Dollar symbol

1.9 release & 2.0-beta

Page 9: Dollar symbol

jquery.migrate

http://code.jquery.com/jquery-migrate-1.0.0.js

Page 10: Dollar symbol

Module Dependency

Page 11: Dollar symbol

Module Dependency

Page 12: Dollar symbol

File concat

Module Dependency

Page 13: Dollar symbol

File concat

Module Dependency

Page 14: Dollar symbol

File concat

Module Dependency

Page 15: Dollar symbol

File concat RequireJS

Module Dependency

Page 16: Dollar symbol

File concat RequireJS

Module Dependency

Page 17: Dollar symbol

File Concat (before v1.11)

•intro.js •core.js •selector.js •… •… •outro.js

Page 18: Dollar symbol

File Concat (before v1.11)

•intro.js •core.js •selector.js •… •… •outro.js

jQuery.jsConcat

Page 19: Dollar symbol

RequireJS (After v1.11)•core/ •var/ •event/ •…./ •jquery.js •core.js •event.js •selector.js •… •…

Page 20: Dollar symbol

RequireJS (After v1.11)•core/ •var/ •event/ •…./ •jquery.js •core.js •event.js •selector.js •… •…

dependency resolve

r.js

Page 21: Dollar symbol

RequireJS (After v1.11)•core/ •var/ •event/ •…./ •jquery.js •core.js •event.js •selector.js •… •…

dependency resolve

r.js convert

wrap

output

Page 22: Dollar symbol

RequireJS (After v1.11)•core/ •var/ •event/ •…./ •jquery.js •core.js •event.js •selector.js •… •…

dependency resolve

r.js convert

wrap

output

Page 23: Dollar symbol

RequireJS (After v1.11)•core/ •var/ •event/ •…./ •jquery.js •core.js •event.js •selector.js •… •…

dependency resolve

r.js convert

wrap

output

jQuery.js

Page 24: Dollar symbol

熱⾝身⼀一下來看看 jQuery.ready 在不同版本下的實作差異

Page 25: Dollar symbol

注:$(document).ready 沒事不要⽤用但是很多⼈人都⽤用過,所以拿來熱⾝身

Page 26: Dollar symbol

// $.fn.ready #1$(document).ready(function(){ // callback content.});

Page 27: Dollar symbol

// $.fn.ready #2$(function(){ // callback content.});

// $.fn.ready #1$(document).ready(function(){ // callback content.});

Page 28: Dollar symbol

Challenge

Page 29: Dollar symbol

// Kick off the DOM ready check even if the user does notjQuery.ready.promise();

Challenge

Page 30: Dollar symbol

// Kick off the DOM ready check even if the user does notjQuery.ready.promise();

http://macb.in/do3E

Challenge

Page 31: Dollar symbol

Contribution

Page 32: Dollar symbol

Contribution

Page 33: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

Page 34: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

Page 35: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

MIT/GPL

Page 36: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

MIT/GPL

Page 37: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

MIT/GPL

Page 38: Dollar symbol

License

http://blog.jquery.com/2012/09/10/jquery-licensing-changes/

MIT/GPL

MIT

Page 39: Dollar symbol

Sign the CLA(Contributor License Agreement)

http://contribute.jquery.org/CLA/

Page 40: Dollar symbol

⼯工具

Page 41: Dollar symbol

• vim

Page 42: Dollar symbol

• vim • ctags

Page 43: Dollar symbol

• vim • ctags • sliver_search or ack

Page 44: Dollar symbol

Or Just use your browser

Page 45: Dollar symbol

讓你的 GitHub ⽤用起來更⽜牛⼀一點

Page 46: Dollar symbol

熟記 shortcut

Page 47: Dollar symbol

熟記 shortcut按 “t” 就對了

Page 48: Dollar symbol

Octotreehttp://sobolev.us/octotree/

Page 49: Dollar symbol

Sourcegraphhttps://sourcegraph.com/

Page 50: Dollar symbol

Github-findhttp://goo.gl/DR86r1

Page 51: Dollar symbol

Take a break

Page 52: Dollar symbol

jQuery.fn.inita jQuery Object

Page 53: Dollar symbol

$('div')$('#id')$('.class')$('<div/>')

Page 54: Dollar symbol

$('div')$('#id')$('.class')$('<div/>')

Page 55: Dollar symbol

$('div')$('#id')$('.class')$('<div/>')

console.log($('#id')); //[<div id="id"></id>]

Page 56: Dollar symbol

window.jQuery = window.$ = jQuery;

https://github.com/jquery/jquery/blob/master/src/exports/global.js

src/exports/global.js

Page 57: Dollar symbol

// Define a local copy of jQuery jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context ); },

Page 58: Dollar symbol

各種狀況判斷

Page 59: Dollar symbol

各種狀況判斷(防衛

)

Page 60: Dollar symbol

// A central reference to the root jQuery(document)var rootjQuery,

// A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

init = jQuery.fn.init = function( selector, context ) { var match, elem;

// HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; }

// Handle HTML strings if ( typeof selector === "string" ) { if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ];

} else { match = rquickExpr.exec( selector ); }

Page 61: Dollar symbol

// A central reference to the root jQuery(document)var rootjQuery,

// A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

init = jQuery.fn.init = function( selector, context ) { var match, elem;

// HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; }

// Handle HTML strings if ( typeof selector === "string" ) { if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ];

} else { match = rquickExpr.exec( selector ); }

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Page 62: Dollar symbol

Selector 以外的狀況

// HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; }

// HANDLE: $(function) // Shortcut for document ready } else if ( jQuery.isFunction( selector ) ) { return typeof rootjQuery.ready !== "undefined" ? rootjQuery.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); }

Page 63: Dollar symbol

Selector & HTML

Page 64: Dollar symbol

// A central reference to the root jQuery(document)var rootjQuery,

// A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

init = jQuery.fn.init = function( selector, context ) { var match, elem;

// HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; }

// Handle HTML strings if ( typeof selector === "string" ) { if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ];

} else { match = rquickExpr.exec( selector ); }

Page 65: Dollar symbol

// A central reference to the root jQuery(document)var rootjQuery,

// A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

init = jQuery.fn.init = function( selector, context ) { var match, elem;

// HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; }

// Handle HTML strings if ( typeof selector === "string" ) { if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ];

} else { match = rquickExpr.exec( selector ); }

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Page 66: Dollar symbol

$('#id')$('<div/>')

Page 67: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Page 68: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing

Page 69: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1

Page 70: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

Page 71: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

Page 72: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

Page 73: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

• match[0] = // Matched String

Page 74: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

• match[0] = // Matched String

• match[1] = // Tag html

Page 75: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

• match[0] = // Matched String

• match[1] = // Tag html

• match[2] = // ID name

Page 76: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

• match[0] = // Matched String

• match[1] = // Tag html

• match[2] = // ID name $('#id')

Page 77: Dollar symbol

rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/

Non-capturing Group 1 Group 2

match = rquickExpr.exec( selector );

• match[0] = // Matched String

• match[1] = // Tag html

• match[2] = // ID name $('#id')

$('<div/>'

)

Page 78: Dollar symbol

// Handle HTML strings if ( typeof selector === "string" ) { if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ];

} else { match = rquickExpr.exec( selector ); }

Page 79: Dollar symbol

// Match html or make sure no context is specified for #id if ( match && (match[1] || !context) ) {

// HANDLE: $(html) -> $(array) if ( match[1] ) { context = context instanceof jQuery ? context[0] : context;

// Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[1], context && context.nodeType ? context.ownerDocument || context : document, true ) );

// HANDLE: $(html, props) if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( jQuery.isFunction( this[ match ] ) ) { this[ match ]( context[ match ] );

// ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); }

Page 80: Dollar symbol

// ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } }

return this;

// HANDLE: $(#id) } else { elem = document.getElementById( match[2] );

// Support: Blackberry 4.6 // gEBID returns nodes no longer in the document (#6963) if ( elem && elem.parentNode ) { // Inject the element directly into the jQuery object this.length = 1; this[0] = elem; }

this.context = document; this.selector = selector; return this; }

Page 81: Dollar symbol

this.context = document; this.selector = selector; return this; }

// HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector );

// HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); }

Page 82: Dollar symbol

jQuery.find = Sizzle;

Page 83: Dollar symbol

Sizzle core

Page 84: Dollar symbol

function Sizzle( selector, context, results, seed )

Page 85: Dollar symbol

node typeName ValueELEMENT_NODE 1

ATTRIBUTE_NODE 2

TEXT_NODE 3

CDATA_SECTION_NODE 4

ENTITY_REFERENCE_NODE 5

ENTITY_NODE 6

PROCESSING_INSTRUCTION_NODE 7

COMMENT_NODE 8

DOCUMENT_NODE 9

DOCUMENT_TYPE_NODE 10

DOCUMENT_FRAGMENT_NODE 11

NOTATION_NODE 12

Page 86: Dollar symbol

node typeName ValueELEMENT_NODE 1

ATTRIBUTE_NODE 2

TEXT_NODE 3

CDATA_SECTION_NODE 4

ENTITY_REFERENCE_NODE 5

ENTITY_NODE 6

PROCESSING_INSTRUCTION_NODE 7

COMMENT_NODE 8

DOCUMENT_NODE 9

DOCUMENT_TYPE_NODE 10

DOCUMENT_FRAGMENT_NODE 11

NOTATION_NODE 12

Page 87: Dollar symbol

var match, elem, m, nodeType, // QSA vars i, groups, old, nid, newContext, newSelector;

if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); }

context = context || document; results = results || []; nodeType = context.nodeType;

if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

return results; }

Page 88: Dollar symbol

var match, elem, m, nodeType, // QSA vars i, groups, old, nid, newContext, newSelector;

if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { setDocument( context ); }

context = context || document; results = results || []; nodeType = context.nodeType;

if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {

return results; }

Page 89: Dollar symbol

if ( !seed && documentIsHTML ) {

// Try to shortcut find operations when possible (e.g., not under DocumentFragment) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document (jQuery #6963) if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document

Page 90: Dollar symbol

if ( !seed && documentIsHTML ) {

// Try to shortcut find operations when possible (e.g., not under DocumentFragment) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document (jQuery #6963) if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document

Page 91: Dollar symbol

rquickExpr

Page 92: Dollar symbol

rquickExprSizzle version

Page 93: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Page 94: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Page 95: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1

Page 96: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2

Page 97: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

Page 98: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );

Page 99: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

Page 100: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

• match[1] = // ID name

Page 101: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

• match[1] = // ID name

• match[2] = // TAG name

Page 102: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

• match[1] = // ID name

• match[2] = // TAG name

• match[3] = // CLASS name

Page 103: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

• match[1] = // ID name

• match[2] = // TAG name

• match[3] = // CLASS name $(‘.class'

)

Page 104: Dollar symbol

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/

Group 1 Group 2 Group 3

match = rquickExpr.exec( selector );• match[0] = // Matched String

• match[1] = // ID name

• match[2] = // TAG name

• match[3] = // CLASS name $(‘.class'

)$('di

v')

Page 105: Dollar symbol

if ( !seed && documentIsHTML ) {

// Try to shortcut find operations when possible (e.g., not under DocumentFragment) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document (jQuery #6963) if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document

Page 106: Dollar symbol

if ( !seed && documentIsHTML ) {

// Try to shortcut find operations when possible (e.g., not under DocumentFragment) if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { if ( nodeType === 9 ) { elem = context.getElementById( m ); // Check parentNode to catch when Blackberry 4.6 returns // nodes that are no longer in the document (jQuery #6963) if ( elem && elem.parentNode ) { // Handle the case where IE, Opera, and Webkit return items // by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } } else { // Context is not a document

Page 107: Dollar symbol

} else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } }

Page 108: Dollar symbol

} else { // Context is not a document if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } }

e.g.,$(‘body’).find(‘#id’)

Page 109: Dollar symbol

// Speed-up: Sizzle("TAG") } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results;

// Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && support.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } }

Page 110: Dollar symbol

// Speed-up: Sizzle("TAG") } else if ( match[2] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results;

// Speed-up: Sizzle(".CLASS") } else if ( (m = match[3]) && support.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } }

Page 111: Dollar symbol

var push = [].push, slice = [].slice;

Page 112: Dollar symbol
Page 113: Dollar symbol

Function.prototype.apply()fun.apply(thisArg[, argsArray])

Page 114: Dollar symbol

Function.prototype.apply()fun.apply(thisArg[, argsArray])

Function.prototype.call()fun.call(thisArg[, arg1[, arg2[, ...]]])

Page 115: Dollar symbol

document.querySelectAll

Page 116: Dollar symbol

// QSA path if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { nid = old = expando; newContext = context; newSelector = nodeType !== 1 && selector;

// qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { groups = tokenize( selector );

if ( (old = context.getAttribute("id")) ) { nid = old.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } nid = "[id='" + nid + "'] ";

i = groups.length; while ( i-- ) { groups[i] = nid + toSelector( groups[i] ); } newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; newSelector = groups.join(","); }

Page 117: Dollar symbol

Challenge

// qSA works strangely on Element-rooted queries// We can work around this by specifying an extra ID on the root// and working up from there (Thanks to Andrew Dupont for the technique)// IE 8 doesn't work on object elements

Page 118: Dollar symbol

http://macb.in/1fDSb

Challenge

// qSA works strangely on Element-rooted queries// We can work around this by specifying an extra ID on the root// and working up from there (Thanks to Andrew Dupont for the technique)// IE 8 doesn't work on object elements

Page 119: Dollar symbol

// QSA path if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { nid = old = expando; newContext = context; newSelector = nodeType !== 1 && selector;

// qSA works strangely on Element-rooted queries // We can work around this by specifying an extra ID on the root // and working up from there (Thanks to Andrew Dupont for the technique) // IE 8 doesn't work on object elements if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { groups = tokenize( selector );

if ( (old = context.getAttribute("id")) ) { nid = old.replace( rescape, "\\$&" ); } else { context.setAttribute( "id", nid ); } nid = "[id='" + nid + "'] ";

i = groups.length; while ( i-- ) { groups[i] = nid + toSelector( groups[i] ); } newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; newSelector = groups.join(","); }

Page 120: Dollar symbol

if ( newSelector ) { try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } }

Page 121: Dollar symbol

Take a break

Page 122: Dollar symbol

Deferred⾯面試必備的知識

Page 123: Dollar symbol

Async JavaScript好書推薦給你

Page 124: Dollar symbol
Page 125: Dollar symbol

• Callback

Page 126: Dollar symbol

• Callback• Event

Page 127: Dollar symbol

• Callback• Event• Promise

Page 128: Dollar symbol

Callback

Page 129: Dollar symbol

Callback

Page 130: Dollar symbol

Callback

Page 131: Dollar symbol

Callback

Callback Hell

Page 132: Dollar symbol

Events

Page 133: Dollar symbol

Promise patternhttp://wiki.commonjs.org/wiki/Promises

Page 134: Dollar symbol

Promise patternhttp://wiki.commonjs.org/wiki/Promises

許你⼀一個承諾

Page 135: Dollar symbol

Promise patternhttp://wiki.commonjs.org/wiki/Promises

許你⼀一個承諾

Page 136: Dollar symbol

jQuery.Deferred()

• A constructor function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.

• jQuery Deferred is based on the CommonJS Promises/A design.

Page 137: Dollar symbol
Page 138: Dollar symbol

郭董說

Page 139: Dollar symbol

$.when(OpenDataAt(172800)) .then(resumeWork) .fail(undefined);

郭董說

Page 140: Dollar symbol

$.when(OpenDataAt(172800)) .then(resumeWork) .fail(undefined);

郭董說

48 ⼩小時內公開資料

Page 141: Dollar symbol

$.when(OpenDataAt(172800)) .then(resumeWork) .fail(undefined);

郭董說

48 ⼩小時內公開資料

復⼯工

Page 142: Dollar symbol

$.when(OpenDataAt(172800)) .then(resumeWork) .fail(undefined);

郭董說

48 ⼩小時內公開資料

復⼯工

不然他也不知道該怎麼辦

Page 143: Dollar symbol

• .ready • .ajax • .animate

Page 144: Dollar symbol

$.Deferred 解析

Page 145: Dollar symbol

了解 Deferred

Page 146: Dollar symbol

了解 Deferred

•⾏行為

Page 147: Dollar symbol

了解 Deferred

•⾏行為

•假設

Page 148: Dollar symbol

了解 Deferred

•⾏行為

•假設

•狀態

Page 149: Dollar symbol

了解 Deferred

•⾏行為

•假設

•狀態

(resolve, reject, notify)

Page 150: Dollar symbol

了解 Deferred

•⾏行為

•假設

•狀態

(resolve, reject, notify)

(done, fail, progress)

Page 151: Dollar symbol

了解 Deferred

•⾏行為

•假設

•狀態

(resolve, reject, notify)

(done, fail, progress)

(resolved, rejected, pending)

Page 152: Dollar symbol
Page 153: Dollar symbol

• deferred.promise() -> state: pending

Page 154: Dollar symbol

• deferred.promise() -> state: pending

• deferred.resolve() -> deferred.done_stack -> state: resolved

Page 155: Dollar symbol

• deferred.promise() -> state: pending

• deferred.resolve() -> deferred.done_stack -> state: resolved

• deferred.reject() -> deferred.fail_stack -> state: rejected

Page 156: Dollar symbol

Deferred 建構式

Page 157: Dollar symbol

Deferred: function( func ) { var tuples = [ // action, add listener, listener list, final state [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) {

Page 158: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

Page 159: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為

Page 160: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設

Page 161: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態

Page 162: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態Callback list

Page 163: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態

0Callback list

Page 164: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態

0 1Callback list

Page 165: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態

0 1 2Callback list

Page 166: Dollar symbol

var tuples = [ [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ],

⾏行為 假設 狀態

0 1 2Callback list

3

Page 167: Dollar symbol

想⼀一想

Page 168: Dollar symbol

想⼀一想

• Deferred 會建構⼀一個全新並獨⽴立的 callbacks list

Page 169: Dollar symbol

想⼀一想

• Deferred 會建構⼀一個全新並獨⽴立的 callbacks list

• 三個⾏行為定義的 function 幾乎⼀一樣

Page 170: Dollar symbol

想⼀一想

• Deferred 會建構⼀一個全新並獨⽴立的 callbacks list

• 三個⾏行為定義的 function 幾乎⼀一樣

• Callbacks list 提供了所有的必要⽅方法, 包含 add, remove, fire, disable

Page 171: Dollar symbol

想⼀一想

• Deferred 會建構⼀一個全新並獨⽴立的 callbacks list

• 三個⾏行為定義的 function 幾乎⼀一樣

• Callbacks list 提供了所有的必要⽅方法, 包含 add, remove, fire, disable

• Resolve 跟 Reject 是相對的

Page 172: Dollar symbol

想⼀一想

• Deferred 會建構⼀一個全新並獨⽴立的 callbacks list

• 三個⾏行為定義的 function 幾乎⼀一樣

• Callbacks list 提供了所有的必要⽅方法, 包含 add, remove, fire, disable

• Resolve 跟 Reject 是相對的

• resolve() 與 reject() 其中⼀一⽅方作動, 另⼀一個的 callbacks 則觸發 .disabled()

Page 173: Dollar symbol

deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 3 ];

// promise[ done | fail | progress ] = list.add promise[ tuple[1] ] = list.add;

// Handle state if ( stateString ) { list.add(function() { // state = [ resolved | rejected ] state = stateString;

// [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); }

// deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; });

Page 174: Dollar symbol

list.add(function() { // state = [ resolved | rejected ] state = stateString;

// [ reject_list | resolve_list ].disable; progress_list.lock }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); }

// deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; }); // Make the deferred a promise promise.promise( deferred );

// Call given func if any if ( func ) { func.call( deferred, deferred ); }

// All done! return deferred; },

Page 175: Dollar symbol

再回到建構式

Page 176: Dollar symbol

Deferred: function( func ) { var tuples = [ // action, add listener, listener list, final state [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], [ "notify", "progress", jQuery.Callbacks("memory") ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise()

Page 177: Dollar symbol

then: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer deferred[ tuple[1] ](function() { var returned = fn && fn.apply( this, arguments ); if ( returned && jQuery.isFunction( returned.promise ) ) { returned.promise() .done( newDefer.resolve ) .fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; }

Page 178: Dollar symbol

.fail( newDefer.reject ) .progress( newDefer.notify ); } else { newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); } }); }); fns = null; }).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {};

Page 179: Dollar symbol

done vs then

Page 180: Dollar symbol

$.Deferred(function(dfd){ dfd .done(function(){ $('#foo').fadeIn(); }) .done(function(){ $('#bar').fadeOut(); });}).resolved();

$.Deferred(function(dfd){ dfd .then(function(){ $('#foo').fadeIn(); }) .then(function(){ $('#bar').fadeOut(); });}).resolved();

Page 181: Dollar symbol

done

• deferred 對象始終是同⼀一個

• done 定義的 callback 都在同⼀一個 stack list

• resolve 之後 callbacks 是近乎同時呼叫

• 不應該預期 callbacks 會照順序執⾏行

Page 182: Dollar symbol

then

• 每次都會建構⼀一個新的 deferred 物件

• then 定義的 callback 都是在⼀一個獨⽴立的 callbacks list

• 順序呼叫多次不同 deferred 物件的 resolved

• 預期是循序執⾏行

Page 183: Dollar symbol

尾聲

Page 184: Dollar symbol

再推薦兩本必須看完的書

Page 185: Dollar symbol

JavaScript:The Good Parts

Page 186: Dollar symbol

Eloquent JavaScript

2nd edition

Page 187: Dollar symbol
Page 188: Dollar symbol

⼈人不⼀一定要⾛走出⾃自⼰己的舒適圈

Page 189: Dollar symbol

⼈人不⼀一定要⾛走出⾃自⼰己的舒適圈

或許也可以考慮擴⼤大⾃自⼰己的舒適圈

Page 190: Dollar symbol

Question

Page 191: Dollar symbol

前端⼯工程師 ⽕火熱加開中

http://jobs.kktix.cc