jquery 原始碼解讀
jquery 原始碼大概10000多行,每行都會解析可能不是很現實,可能也只會更新一版,這都看心情。
(function(global,factory){...})()
在這部分主要就是匿名函式
註釋:匿名函式的好處:自執行裡面所有東西都是區域性的,防止和程式碼衝突。
那如何獲取匿名函式裡面的方法和屬性呢?
可以在裡面掛在一個物件上,比如掛在windows上面
(function (){
function abc (){}
window.abc = abc
})()
abc()
"use strict"
js的嚴禁模式;
在js嚴格模式,對js做了一些限制,主要有以下作用:
1.消除js語法不合理,不嚴謹的,減少怪異行為
2.消除程式碼執行的一些不安全之處
3.提高編譯效率,加強執行速度。
4.對未來新版本做好鋪墊。
語法的改變:
1.全域性命名必須是 v=1 其他變數var
2.禁止使用with 創設 eval作用域。
3.禁止this 指向全域性window
4.禁止內部函式遍歷呼叫棧
function f1(){
f1.caller 報錯
f1.arguments 報錯
}
5.禁止刪除變數,只有在configurable 設定為true
6.使用get方法賦值會報錯。
var o = {
get v(){return 1;}
}
o.v() =2 //報錯
7.刪除一個不可刪除的屬性, delete Object.prototype.
8.重新命名錯誤
9.引數名重複錯誤。
10.禁止八進位制
11.對arguments 引數做了限制。比如不能複製,不能追蹤引數變化,不能用callee。
12.函式宣告在頂層,不許在非函式程式碼內宣告函式
13.保留字
( typeof window !== "undefined" ? window : this, function( window, noGlobal )
這句話很清楚 判斷window 返回型別。
typeof 可以判斷 object undefined null boolean number string Symbol functuon在ECMA-262條款中實現了
var arr = [];
var document = window.document;
var getProto = Object.getPrototypeOf;
var slice = arr.slice;
var concat = arr.concat;
var push = arr.push;
var indexOf = arr.indexOf;
var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;
var fnToString = hasOwn.toString;
var ObjectFunctionString = fnToString.call( Object );
var support = {};
上面聲明瞭一些方法和一些變數。
slice 這個方法,陣列中返回選定得元素。 用法arr.slice(start,end) start -1 最後一個元素。 這個方法會返回一個新陣列。
var isFunction = function isFunction( obj ) {
// Support: Chrome <=57, Firefox <=52
// In some browsers, typeof returns "function" for HTML <object> elements
// (i.e., `typeof document.createElement( "object" ) === "function"`).
// We don't want to classify *any* DOM node as a function.
return typeof obj === "function" && typeof obj.nodeType !== "number";
};
var isWindow = function isWindow( obj ) {
return obj != null && obj === obj.window;
};
var preservedScriptAttributes = {
type: true,
src: true,
noModule: true
};
function DOMEval( code, doc, node ) {
doc = doc || document;
var i,
script = doc.createElement( "script" );
script.text = code;
if ( node ) {
for ( i in preservedScriptAttributes ) {
if ( node[ i ] ) {
script[ i ] = node[ i ];
}
}
}
doc.head.appendChild( script ).parentNode.removeChild( script );
}
function toType( obj ) {
if ( obj == null ) {
return obj + "";
}
// Support: Android <=2.3 only (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call( obj ) ] || "object" :
typeof obj;
}
/* global Symbol */
// Defining this global in .eslintrc.json would create a danger of using the global
// unguarded in another place, it seems safer to define global only for this module
一些程式碼,工具類吧 …
version = "3.3.1", 版本號
jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
},
翻譯是建構函式的增強。可能是用來報錯的吧。
jQuery.fn = jQuery.prototype = {
jquery: version,
constructor: jQuery,
length: 0, //在這裡看了下這個物件的長度.
toArray: function() {
return slice.call( this );
}, 居然是操作DOM的方法.尷尬...
get: function( num ) {
if ( num == null ) {
return slice.call( this );
}
return num < 0 ? this[ num + this.length ] : this[ num ];
},
pushStack: function( elems ) {
// Build a new jQuery matched element set
var ret = jQuery.merge( this.constructor(), elems );
// Add the old object onto the stack (as a reference)
ret.prevObject = this;
// Return the newly-formed element set
return ret;
},
// Execute a callback for every element in the matched set.
each: function( callback ) {
return jQuery.each( this, callback );
},
map: function( callback ) {
return this.pushStack( jQuery.map( this, function( elem, i ) {
return callback.call( elem, i, elem );
} ) );
},
slice: function() {
return this.pushStack( slice.apply( this, arguments ) );
},
first: function() {
return this.eq( 0 );
},
last: function() {
return this.eq( -1 );
},
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 );
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
},
end: function() {
return this.prevObject || this.constructor();
},
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
push: push,
sort: arr.sort,
splice: arr.splice
};
上面的方法都是DOM操作的。很幽默哦~ 當然當年jquery最主要的核心就是選擇器,那麼當年最輝煌的就是dom操作吧。
jQuery.extend = jQuery.fn.extend = function() {
程式碼補充,如果之前寫了 那麼將會被覆蓋~