jQuery源码的基础知识

序言:DOM addEventListener

attachEvent与addEventListener区别
适应的浏览器版本不同,同时在使用的过程中要注意
attachEvent方法          按钮onclick
addEventListener方法    按钮click

一、arguments对象:

1、arguments 属性

为当前执行的function对象返回一个arguments对象。 

2、function.arguments

function参数是当前执行函数的名称,可以省略。 

3、arguments.length

arguments 对象的 length 属性包含了传递给函数的参数的数目。arguments 对象所包含的单个参数,访问方法与数组中所包含的参数的访问方法相同。 

4、arguments当作数组使用

arguments虽然不是数组,但可以当作数组使用,下标由 0 开始,所以:

arguments[0]  表示接收的第一个参数
arguments[1]  表示接收的第二个参数
……

for (var i = 1; i < arguments.length; i++)

   var s = arguments[i];    

5、arguments转换数组

var args = Array.prototype.slice.call(arguments); 

二、call方法:

语法:call([thisObj[,arg1[, arg2[,   [,.argN]]]]])

定义:调用一个对象的一个方法,以另一个对象替换当前对象。

说明:

call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。

如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。 

三、apply方法:

语法:apply([thisObj[,argArray]])

定义:应用某一对象的一个方法,用另一个对象替换当前对象。

说明:

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。

如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。 

四、call方法和apply方法的区别

call和apply方法通常被用来实现类似继承一样的功能,以达到代码复用的功效。它们的区别主要体现在参数上。

Apply:

var v = new fn( " str " ); 

// 上一句相当于下面的代码 

var v = {}; 

fn.apply(v, [ "str" ]);

五、prototype原型

1、当我们使用javascript定义一个类的时候,系统会自动生成一个对应的原型,而使用类的prototype可以指向这个原型。 

2、定义类的时候,一般使用函数定义,而那个函数就是构造函数,构造函数可以使用constructor来指定。 

3、当构造函数和prototype定义了相同的属性或者方法的时候,构造函数的优先级要更高。 

4、原型中,不能调用构造函数的私有变量,和通过传参传进来的值。

 5、prototype中定义的变量和属性都是公有的。 

 6、任何一个类,当有多次实例化的时候,在内存中只有一个原型,而构造函数在内存中会有多个副本。 

7、在构造函数中可以调用prototype中的属性和方法。 

实例:

function fn(){};

fn.prototype={

    pro:'原型'

}

var o=new fn();

alert(o.pro); 

六、匿名函数自动执行(function(){……}())

1. 什么是自执行的匿名函数?

它是指形如这样的函数: (function {// code})();

 2. 疑问

 为什么(function {// code})();可以被执行, 而function {// code}();却会报错?

 3. 分析

(1). 首先, 要清楚两者的区别:

 (function {// code})是表达式, function {// code}是函数声明.

 (2). 其次, js"预编译"的特点:

js在"预编译"阶段, 会解释函数声明, 但却会忽略表式.

 (3). 当js执行到function() {//code}();时, 由于function() {//code}在"预编译"阶段已经被解释过, js会跳过function(){//code}, 试图去执行();, 故会报错;

当js执行到(function {// code})();时, 由于(function {// code})是表达式, js会去对它求解得到返回值, 由于返回值是一 个函数, 故而遇到();时, 便会被执行.

另外, 函数转换为表达式的方法并不一定要靠分组操作符(),我们还可以用void操作符,~操作符,!操作符……

如: 

!function(){      alert("另类的匿名函数自执行");    }(); 

七、自定义的extend静态方法

方法一:

var fn=function(){};

fn.extend = function(o, p) {    

    if ( !p ) {

    p = o; o = this;

    }    

    for ( var i in p )

    o[ i ] = p[  i ];

    alert(o[ i ]);

    alert(o);

    return o;

}

fn.extend({

      method:function(){

           alert("静态方法");

      }

});

fn.method(); //静态方法

方法二:

var fn=function(){};

fn.extend = function() {   

    var options,

    target = arguments[0] || {};

    if ( !options ) {

        options = target; target = this;

    }    

    for ( var i in options )

    target[ i ] = options[  i ];//执行对象直接量,把options[  i ]装载到target[ i ],最后返回target新对象。

    return target;

}

fn.extend({

      method:function(){

           alert("静态方法");

      }

});

fn.method();

源码解析如下:

 var options={
            a:function(){
                alert("a");
            },
            b:function(){
                alert("b");
            }
        }
        var target={};
        for ( var i in options )
        target[i]=options[i];//复制对象,重新装载
        
        target.a(); //a

  

                                    

 

方法三:

var fn=function(){};

Object.extend = function(destination, source) {

  for (property in source) {

     destination[property] = source[property];

  }

  return destination;

}

Object.prototype.extend = function(object) {

  return Object.extend.apply(this, [this, object]);

}

 

fn.extend({

      method:function(){

           alert("静态方法");

      }

});

fn.method();
原文地址:https://www.cnblogs.com/sntetwt/p/2962413.html