搜索
首页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]

首先如果参数objundefinednull,则通过String(obj)转换为对应的原始字符串“undefined”或“null”。

然后class2type[toString.call(obj)]首先借用Object的原型方法toString()来获取obj的字符串表示,返回值的形式是 [object class],其中的class是内部对象类。

然后从对象class2type中取出[object class]对应的小写字符串并返回;如果未取到则一律返回“object

get方法

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

取集合中对应指定索引的值,如果idx小于0,则idx等于idx+length,length为集合的长度.

可能你刚看到slice.call(this)会觉得很纳闷,其实不仅是zepto.js的源码,包括jQuerybackbone的源码都是这么写的,只不过它们在最开头做了声明:

var push = array.push;var slice = array.slice;var splice = array.splice;

所以slice.call(this)其实还是Array.slce.call(this)

prototype.js源码

  //为对象添加 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;
    },

因为addClassName依赖于removeClassName(),所以先分析后者,$()是先将元素封装成prototype对象,

if(!element)  return

这句的意思就是如果元素对象不存在,则忽略不再继续执行的意思,也就是终止的意思。

split() 方法用于把一个字符串分割成字符串数组。

如果把空字符串 ("") 用作 分隔符,那么 该对象 中的每个字符之间都会被分割。

判断是否拥有 class 属性值

//是否拥有 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;//返回错误的处理结果},

兼容旧版本浏览器增加Array的push方法

/**
 * 为兼容旧版本的浏览器增加 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;
    }
}

!Array.prototype.push如果为true,说明浏览器不支持该方法,则往下执行。this[startLength + i] = arguments[i]将传递进来的每个参数依次放入数组中,最后返回数组的长度

访问对象可以使用(.)表示法,也可以使用[]来访问,同样访问数组元素也是

jQuery 源码

jQuery源码太多关联了,所以不好单独拿出来做分析,就举一两个简单的例子吧:

toArray方法

jQuery.prototype = {
    toArray: function() {            return slice.call( this );
        },
}

Array.prototype.slice.call(arguments)能将具有length属性的对象转成数组,也就是说其目的是将arguments对象的数组提出来转化为数组。例如:

<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>

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 + '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(&#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对象字面量的写法

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

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
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),