目錄
underscore.js原始碼
判斷給定變數是否是物件
判斷給定值是否為DOM元素
zepto原始碼
判斷是否是陣列
資料類型判斷
length
prototype
jQuery 源碼
這可以被認為是一個數組的實例方法的命名空間
on方法
jQuery类型判断
首頁 web前端 js教程 有關js框架的原始碼研究

有關js框架的原始碼研究

Aug 10, 2017 pm 01:21 PM
javascript 框架 原始碼

[導讀] 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(&#39;test&#39;);
    alert(t.nodeType);//1
    alert(t.nodeName);//p
    alert(t.nodeValue);//null</script></body>
登入後複製

firstChild屬性

var t = document.getElementById(&#39;test&#39;).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.isArraytrue,則傳回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(&#39;123&#39;)) //[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 undefinednull,則透過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的原始碼,包括jQuerybackbone

的原始碼都是這麼寫的,只不過它們在最開頭做了聲明:

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 += &#39; &#39; + className;
    },   //为对象移除 class 属性值

    removeClassName: function(element, className) {
        element = $(element);        if (!element)            return;        var newClassName = &#39;&#39;;        var a = element.className.split(&#39; &#39;);        for (var i = 0; i < a.length; i++) {            if (a[i] != className) {                if (i > 0)
                    newClassName += &#39; &#39;;
                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)能將具有

length

屬性的物件轉成數組,也就是說其目的是將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(&amp;#39; &amp;#39;); for (var i = 0; i &lt; a.length; i++) { if (a[i] == className) return true;//返回正确的处理结果 } return false;//返回错误的处理结果},</pre><div class="contentsignin">登入後複製</div></div>

Array

這是我們想要的基底物件名稱

prototype

這可以被認為是一個數組的實例方法的命名空間

slice
这提取数组的一部分并返回新的数组,并没有开始和结束索引,它只是返回一个数组的拷贝

call
这是一个非常有用的功能,它允许你从一个对象调用一个函数并且使用它在另一个上下文环境

下面的写法是等效的:

Array.prototype.slice.call == [].slice.call
登入後複製

看这个例子:

object1 = {
    name:&#39;frank&#39;,
    greet:function(){
        alert(&#39;hello &#39;+this.name)
    }
};

object2 = {
    name:&#39;trigkit4&#39;};// object2没有greet方法// 但我们可以从object1中借来

 object1.greet.call(object2);//弹出hello trigkit4
登入後複製

分解一下就是object1.greet运行弹出hello + &#39;this.name&#39;,然后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(&#39;trigkit4&#39;);
登入後複製

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对象字面量的写法

{键:值,键:值}语法中的“健/值”会成为对象的静态成员。如果给某个“健”指定的值是一个匿名函数,那么该函数就会变成对象的静态方法;否则就是对象的一个静态属性。
有關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)。它的作用是改变toStringthis指向为object的实例。

以上是有關js框架的原始碼研究的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何評估Java框架商業支援的性價比 如何評估Java框架商業支援的性價比 Jun 05, 2024 pm 05:25 PM

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

PHP 框架的學習曲線與其他語言框架相比如何? PHP 框架的學習曲線與其他語言框架相比如何? Jun 06, 2024 pm 12:41 PM

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

PHP 框架的輕量級選項如何影響應用程式效能? PHP 框架的輕量級選項如何影響應用程式效能? Jun 06, 2024 am 10:53 AM

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

Java框架的效能比較 Java框架的效能比較 Jun 04, 2024 pm 03:56 PM

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

golang框架文件最佳實踐 golang框架文件最佳實踐 Jun 04, 2024 pm 05:00 PM

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

如何為不同的應用場景選擇最佳的golang框架 如何為不同的應用場景選擇最佳的golang框架 Jun 05, 2024 pm 04:05 PM

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

Java框架學習路線圖:不同領域中的最佳實踐 Java框架學習路線圖:不同領域中的最佳實踐 Jun 05, 2024 pm 08:53 PM

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

Golang框架學習過程中常見的迷思有哪些? Golang框架學習過程中常見的迷思有哪些? Jun 05, 2024 pm 09:59 PM

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

See all articles