有關js框架的原始碼研究
[導讀] underscore js原始碼Underscore js 沒有對原生 JavaScript 物件進行擴充,而是透過呼叫 _() 方法進行封裝,一旦封裝完成,原生 JavaScript 物件就會成為 Underscore 物件。判斷給定變數是否是物件 Is
underscore.js原始碼
#Underscore.js
沒有對原生JavaScript
物件進行擴充,而是透過呼叫_()
方法來封裝,一旦封裝完成,原生JavaScript
物件就會成為一個Underscore
物件。
判斷給定變數是否是物件
// Is a given variable an object? _.isObject = function(obj) { var type = typeof obj; return type === 'function' || type === 'object' && !!obj; };
這是underscore.js
的判斷給定變數是否是object
的一段原始碼。 我們知道typeof
會傳回以下六個值:
1. 'undefined' --- 这个值未定义;2. 'boolean' --- 这个值是布尔值;3. 'string' --- 这个值是字符串;4. 'number' --- 这个值是数值;5. 'object' --- 这个值是对象或null;6. 'function' --- 这个值是函数。
而&&
的優先權要高與||
。 !!
的作用相當於Boolean()
,將其轉換為布林值。
判斷給定值是否為DOM元素
// Is a given value a DOM element? _.isElement = function(obj) { return !!(obj && obj.nodeType === 1); };
同樣!!
相當於Boolean()
的作用,nodeType == = 1
則說明是元素節點,屬性attr
是2 ,文字text
是3
<body> <p id="test">测试</p><script> var t = document.getElementById('test'); alert(t.nodeType);//1 alert(t.nodeName);//p alert(t.nodeValue);//null</script></body>
firstChild
屬性
var t = document.getElementById('test').firstChild; alert(t.nodeType);//3alert(t.nodeName);//#testalert(t.nodeValue);//测试
文字節點也算是節點,所以p的子節點是文字節點,所以回傳3
zepto原始碼
判斷是否是陣列
isArray = Array.isArray || function(object){ return object instanceof Array }
#Array.isArray()
方法:如果一個物件是數組就回傳true
,如果不是則回傳false
。
instanceof
用來判斷變數是否某個物件的實例,如
var a= []; alert(a instanceof Array);//返回 true
同時alert(a instanceof Object)
也會回傳true
isArray
傳回布林值,如果Array.isArray
為true
,則傳回true
,否則傳回object instanceof Array
的結果。
資料類型判斷
class2type = {},function type(obj) { return obj == null ? String(obj) : class2type[toString.call(obj)] || "object" } function isFunction(value) { return type(value) == "function" } function isWindow(obj) { return obj != null && obj == obj.window } function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } function isObject(obj) { return type(obj) == "object" }
class2type
是一個空對象,實際上一個什麼都沒有的空對像是這樣建立的Object.create(null) ;
我們可以透過Object.prototype.toString.call()
方法來判斷資料類型,例如:
console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call('123')) //[object String] console.log(Object.prototype.toString.call(undefined)) //[object Undefined] console.log(Object.prototype.toString.call(true)) //[object Boolean] console.log(Object.prototype.toString.call({})) //[object Object] console.log(Object.prototype.toString.call([])) //[object Array] console.log(Object.prototype.toString.call(function(){})) //[object Function]
首先如果參數obj
是undefined
或null
,則透過String(obj)
轉換為對應的原始字串“undefined
”或“ null
」。
然後class2type[toString.call(obj)]
先借用Object
的原型方法toString()
來取得obj
的字串表示,傳回值的形式是[object class]
,其中的class
是內部物件類別。
然後從物件class2type
中取出[object class]
對應的小寫字串並傳回;如果未取到則一律傳回「object
。 +length
length
為集合的長度.可能你剛剛看到
slice.call(this)會覺得很納悶,其實不只
zepto.js的原始碼,包括
jQuery,
backbone
get: function(idx){ return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] },
所以
slice.call(this)其實還是
Array.slce.call(this)
prototype.js原始碼
var push = array.push;var slice = array.slice;var splice = array.splice;
addClassName依賴
removeClassName(),所以先分析後者,
$()
prototype
對象,//为对象添加 class 属性值 addClassName: function(element, className) { element = $(element); Element.removeClassName(element, className); element.className += ' ' + className; }, //为对象移除 class 属性值 removeClassName: function(element, className) { element = $(element); if (!element) return; var newClassName = ''; var a = element.className.split(' '); for (var i = 0; i < a.length; i++) { if (a[i] != className) { if (i > 0) newClassName += ' '; newClassName += a[i]; } } element.className = newClassName; },
這句話的意思是如果元素物件不存在,則忽略不再繼續執行的意思,也就是終止的意思。 ##) 用作分隔符,那麼該物件中的每個字元之間都會被分割。方法
if(!element) return
!Array.prototype.push如果為
true,表示瀏覽器不支援該方法,則往下執行。 i] = arguments[i]
將傳遞進來的每個參數依序放入陣列中,最後傳回陣列的長度存取物件可以使用
(.)表示法,也可以使用[]
來訪問,同樣訪問數組元素也是
jQuery 源碼
jQuery源碼太多關聯了,所以不好單獨拿出來做分析,就舉一兩個簡單的例子:toArray方法
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>split() 方法用于把一个字符串分割成字符串数组。</pre><div class="contentsignin">登入後複製</div></div>
Array.prototype.slice.call(arguments)
能將具有
屬性的物件轉成數組,也就是說其目的是將arguments
物件的陣列提出來轉換為數組。例如:<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>//是否拥有 class 属性值hasClassName: function(element, className) {
element = $(element); if (!element) return; var a = element.className.split(&#39; &#39;); for (var i = 0; i < a.length; i++) { if (a[i] == className) return true;//返回正确的处理结果
} return false;//返回错误的处理结果},</pre><div class="contentsignin">登入後複製</div></div>
prototype
這可以被認為是一個數組的實例方法的命名空間
slice
这提取数组的一部分并返回新的数组,并没有开始和结束索引,它只是返回一个数组的拷贝
call
这是一个非常有用的功能,它允许你从一个对象调用一个函数并且使用它在另一个上下文环境
下面的写法是等效的:
Array.prototype.slice.call == [].slice.call
看这个例子:
object1 = { name:'frank', greet:function(){ alert('hello '+this.name) } }; object2 = { name:'trigkit4'};// object2没有greet方法// 但我们可以从object1中借来 object1.greet.call(object2);//弹出hello trigkit4
分解一下就是object1.greet
运行弹出hello + 'this.name'
,然后object2
对象冒充,this
就指代object2
var t = function(){ console.log(this);// String [ "t", "r", "i", "g", "k", "i", "t", "4" ] console.log(typeof this); // Object console.log(this instanceof String); // true}; t.call('trigkit4');
call(this)
指向了所传进去的对象。
在Object.prototype
中已经包含了一些方法:
1.toString ( ) 2.toLocaleString ( ) 3.valueOf ( ) 4.hasOwnProperty (V) 5.isPrototypeOf (V) 6.propertyIsEnumerable (V)
on方法
jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } } }) jQuery.extend(object) :为扩展jQuery类本身.为类添加新的方法。 jQuery.fn.extend(object) :给jQuery对象添加方法。
!=
在表达式两边的数据类型不一致时,会隐式转换为相同数据类型,然后对值进行比较.!==
不会进行类型转换,在比较时除了对值进行比较以外,还比较两边的数据类型, 它是恒等运算符===
的非形式。
on : function(){}
是js
对象字面量的写法
{键:值,键:值}
语法中的“健/值”
会成为对象的静态成员。如果给某个“健”指定的值是一个匿名函数,那么该函数就会变成对象的静态方法;否则就是对象的一个静态属性。
jQuery类型判断
type: function( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call(obj) ] || "object" : typeof obj; },
前面已经分析了,class2type = {};
所以class2type[ toString.call(obj) ]
={}.toString.call(obj)
。它的作用是改变toString
的this
指向为object
的实例。
以上是有關js框架的原始碼研究的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

評估Java框架商業支援的性價比涉及以下步驟:確定所需的保障等級和服務等級協定(SLA)保證。研究支持團隊的經驗和專業知識。考慮附加服務,如昇級、故障排除和效能最佳化。權衡商業支援成本與風險緩解和提高效率。

PHP框架的學習曲線取決於語言熟練度、框架複雜性、文件品質和社群支援。與Python框架相比,PHP框架的學習曲線較高,而與Ruby框架相比,則較低。與Java框架相比,PHP框架的學習曲線中等,但入門時間較短。

輕量級PHP框架透過小體積和低資源消耗提升應用程式效能。其特點包括:體積小,啟動快,記憶體佔用低提升響應速度和吞吐量,降低資源消耗實戰案例:SlimFramework創建RESTAPI,僅500KB,高響應性、高吞吐量

根據基準測試,對於小型、高效能應用程序,Quarkus(快速啟動、低記憶體)或Micronaut(TechEmpower優異)是理想選擇。 SpringBoot適用於大型、全端應用程序,但啟動時間和記憶體佔用稍慢。

編寫清晰全面的文件對於Golang框架至關重要。最佳實踐包括:遵循既定文件風格,例如Google的Go程式設計風格指南。使用清晰的組織結構,包括標題、子標題和列表,並提供導覽。提供全面且準確的信息,包括入門指南、API參考和概念。使用程式碼範例說明概念和使用方法。保持文件更新,追蹤變更並記錄新功能。提供支援和社群資源,例如GitHub問題和論壇。建立實際案例,如API文件。

根據應用場景選擇最佳Go框架:考慮應用類型、語言特性、效能需求、生態系統。常見Go框架:Gin(Web應用)、Echo(Web服務)、Fiber(高吞吐量)、gorm(ORM)、fasthttp(速度)。實戰案例:建構RESTAPI(Fiber),與資料庫互動(gorm)。選擇框架:效能關鍵選fasthttp,靈活Web應用選Gin/Echo,資料庫互動選gorm。

針對不同領域的Java框架學習路線圖:Web開發:SpringBoot和PlayFramework。持久層:Hibernate和JPA。服務端響應式程式設計:ReactorCore和SpringWebFlux。即時計算:ApacheStorm和ApacheSpark。雲端運算:AWSSDKforJava和GoogleCloudJava。

Go框架學習的迷思有以下5種:過度依賴框架,限制彈性。不遵循框架約定,程式碼難以維護。使用過時庫,帶來安全和相容性問題。過度使用包,混淆程式碼結構。忽視錯誤處理,導致意外行為和崩潰。
