Home > Web Front-end > JS Tutorial > Source code research on js framework

Source code research on js framework

巴扎黑
Release: 2017-08-10 13:21:30
Original
1476 people have browsed it

[Introduction] Underscore js source code Underscore js does not extend the native JavaScript object, but encapsulates it by calling the _() method. Once the encapsulation is completed, the native JavaScript object becomes an Underscore object. Determine whether a given variable is an object Is

underscore.js source code

Underscore.js does not extend the native JavaScript object, but passes Call the _() method to encapsulate. Once the encapsulation is completed, the native JavaScript object becomes an Underscore object.

Judge whether a given variable is an object

// Is a given variable an object?
    _.isObject = function(obj) {        var type = typeof obj;        return type === 'function' || type === 'object' && !!obj;
    };
Copy after login

This is a source code for underscore.js to judge whether a given variable is an object. We know that typeof will return the following six values:

1. 'undefined' --- 这个值未定义;2. 'boolean'    --- 这个值是布尔值;3. 'string'        --- 这个值是字符串;4. 'number'     --- 这个值是数值;5. 'object'       --- 这个值是对象或null;6. 'function'    --- 这个值是函数。
Copy after login

and && has a higher priority than ||. !! is equivalent to Boolean(), converting it to a Boolean value.

Judge whether the given value is a DOM element

// Is a given value a DOM element?
    _.isElement = function(obj) {        return !!(obj && obj.nodeType === 1);
    };
Copy after login

Similarly !!Equivalent to Boolean(), nodeType == = 1 means it is an element node, the attribute attr is 2, and the text text is 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>
Copy after login

firstChildAttribute

var t = document.getElementById(&#39;test&#39;).firstChild;
alert(t.nodeType);//3alert(t.nodeName);//#testalert(t.nodeValue);//测试
Copy after login

The text node is also a node, so the child node of p is the text node, so return 3

zepto source code

Judge whether it is an array

isArray = Array.isArray ||            function(object){ return object instanceof Array }
Copy after login

Array.isArray() Method: Returns true if an object is an array, and false if not.

instanceof Used to determine whether a variable is an instance of an object, such as

var a= [];
alert(a instanceof Array);//返回 true
Copy after login

At the same time, alert(a instanceof Object) will also returntrue

##isArray Returns a Boolean value. If Array.isArray is true, then true## is returned. #, otherwise return the result of object instanceof Array. Data type judgment

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" }
Copy after login

class2type

is an empty object. In fact, an empty object with nothing is created like thisObject.create(null) ;We can determine the data type through the

Object.prototype.toString.call()

method, for example: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">console.log(Object.prototype.toString.call(123)) //[object Number] console.log(Object.prototype.toString.call(&amp;#39;123&amp;#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]</pre><div class="contentsignin">Copy after login</div></div>First if the parameter

obj

is undefined or null, then use String(obj) to convert it to the corresponding original string "undefined" or " null”. Then

class2type[toString.call(obj)]

First borrow the prototype method of ObjecttoString() to get obj# The string representation of ##, the return value is in the form [object class], where class is the internal object class. Then take out the lowercase string corresponding to [object class]

from the object

class2type and return it; if it is not retrieved, it will always return "object. get method

get: function(idx){            return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
        },
Copy after login

Gets the value corresponding to the specified index in the collection. If

idx

is less than 0, then

idx is equal to idx +length,length is the length of the collection.Maybe you are confused when you just saw slice.call(this)

, but in fact it is not only# The source code of ##zepto.js

, including jQuery, and the source code of backbone are written like this, except that they make a statement at the beginning: <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs php">var push = array.push;var slice = array.slice;var splice = array.splice;</pre><div class="contentsignin">Copy after login</div></div>Soslice.call(this)In fact, it is still

Array.slce.call(this)

prototype.js source code<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript"> //为对象添加 class 属性值 addClassName: function(element, className) { element = $(element); Element.removeClassName(element, className); element.className += &amp;#39; &amp;#39; + className; }, //为对象移除 class 属性值 removeClassName: function(element, className) { element = $(element); if (!element) return; var newClassName = &amp;#39;&amp;#39;; var a = element.className.split(&amp;#39; &amp;#39;); for (var i = 0; i &lt; a.length; i++) { if (a[i] != className) { if (i &gt; 0) newClassName += &amp;#39; &amp;#39;; newClassName += a[i]; } } element.className = newClassName; },</pre><div class="contentsignin">Copy after login</div></div>because

addClassName

depends on

removeClassName()

, so analyze the latter first, $() first encapsulates the elements into prototype objects, <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs coffeescript">if(!element) return</pre><div class="contentsignin">Copy after login</div></div>The meaning of this sentence is that if the element object does not exist, it will be ignored and the execution will not continue, which means to terminate. <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs perl">split() 方法用于把一个字符串分割成字符串数组。</pre><div class="contentsignin">Copy after login</div></div>If the empty string (

""

) is used as a separator, then each character in the object will be separated

Determine whether it has a class attribute value<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">//是否拥有 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">Copy after login</div></div>Compatible with older version browsers to add Array push. Method

/**
 * 为兼容旧版本的浏览器增加 Array 的 push 方法。
 */if (!Array.prototype.push) {    Array.prototype.push = function() {        var startLength = this.length;//this指代Array
        for (var i = 0; i < arguments.length; i++)            this[startLength + i] = arguments[i];//this依旧指代Array
        return this.length;
    }
}
Copy after login

!Array.prototype.push

If it is

true

, it means that the browser does not support this method, and this[startLength + will be executed. i] = arguments[i]Put each parameter passed in into the array in turn, and finally return the length of the arrayYou can use the (.) notation to access the object, You can also use

[]

to access. Similarly, accessing array elements is also jQuery source code

jQuery

The source code is too related, so it is not easy to separate it Let’s take it out for analysis and give one or two simple examples:

toArray method<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="hljs javascript">jQuery.prototype = { toArray: function() { return slice.call( this ); }, }</pre><div class="contentsignin">Copy after login</div></div>

Array.prototype.slice.call(arguments)

can have # The object of the ##length

attribute is converted into an array, which means that its purpose is to extract the array of

arguments objects and convert it into an array. For example:

<script>
    var a = {length:4,0:&#39;zero&#39;,1:&#39;one&#39;,2:&#39;two&#39;};    console.log(Array.prototype.slice.call(a));// Array [ "zero", "one", "two", <1 个空的存储位置> ]</script>
Copy after login
ArrayThis is the base object name we want

prototype
This can be thought of as a Namespace of instance methods of array

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

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

下面的写法是等效的:

Array.prototype.slice.call == [].slice.call
Copy after login

看这个例子:

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
Copy after login

分解一下就是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;);
Copy after login

call(this)指向了所传进去的对象。

Object.prototype中已经包含了一些方法:

    1.toString ( )

    2.toLocaleString ( )

    3.valueOf ( )

    4.hasOwnProperty (V)

    5.isPrototypeOf (V)

    6.propertyIsEnumerable (V)
Copy after login

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对象添加方法。
Copy after login

!= 在表达式两边的数据类型不一致时,会隐式转换为相同数据类型,然后对值进行比较.
!== 不会进行类型转换,在比较时除了对值进行比较以外,还比较两边的数据类型, 它是恒等运算符===的非形式。

on : function(){}js对象字面量的写法

{键:值,键:值}语法中的“健/值”会成为对象的静态成员。如果给某个“健”指定的值是一个匿名函数,那么该函数就会变成对象的静态方法;否则就是对象的一个静态属性。
Source code research on js framework

jQuery类型判断

type: function( obj ) {            if ( obj == null ) {                return obj + "";
            }            return typeof obj === "object" || typeof obj === "function" ?
            class2type[ toString.call(obj) ] || "object" :                typeof obj;
        },
Copy after login

前面已经分析了,class2type = {};所以class2type[ toString.call(obj) ] =
{}.toString.call(obj)。它的作用是改变toStringthis指向为object的实例。

The above is the detailed content of Source code research on js framework. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template