• jquery源码解析:type,isPlainObject,parseHTML,parseXML,globalEval详解


    jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的。

    jQuery.extend({ 

      ......  

      type: function( obj ) {    //$.type(),判断类型
        if ( obj == null ) {   //null,undefined
          return String( obj );    //返回null,undefined字符串
        }     //core_toString = {}.toString 
        return typeof obj === "object" || typeof obj === "function" ?
          class2type[ core_toString.call(obj) ] || "object" :     //number,string等包装类型,typeof判断是object,所以进入到toString判断,最终返回number,string

            typeof obj;       //基本类型,number,string直接用typeof.
      }, 

      isPlainObject: function( obj ) {   //判断是否是对象自变量,{},new Object
        if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
          return false;    //dom节点,window等是object,但是不是对象自变量。
        }

        try {     //window.location是object,core_hasOwn是{}.hasOwnProperty(自己的属性,不是原型的属性)
          if ( obj.constructor && !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            //isPrototypeOf只存在object.prototype对象中,core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" )这句话的意思就是:obj.constructor.prototype是否有isPrototypeOf属性,从上可知,只有object.prototype有,所以只有object.prototype才返回真。比如,我传入一个Person(构造函数),它的原型没有isPrototypeOf属性,所以返回false。Person不是对象自变量。

            return false;
          }//在火狐20以下版本,如果操作window.location.constructor 多次,会抛错
        } catch ( e ) {
          return false;
        }

        return true;
      },

      isEmptyObject: function( obj ) {  //{},[],对象自身下没有属性和方法就返回true。function Person(){} ;var person = new Person(),返回true

        var name;
        for ( name in obj ) {     //系统自带的属性和方法不会for in打印出来。
          return false;
        }
        return true;
      }, 

      parseHTML: function( data, context, keepScripts ) {   //解析字符串为数组节点,比如:"<li></li>" -> [li元素]

        //keepScripts 为true,可以解析script,false不能解析script标签
        if ( !data || typeof data !== "string" ) {  
          return null;
        }
        if ( typeof context === "boolean" ) {   //如果没有第二个参数
          keepScripts = context;
          context = false;
        }
        context = context || document;

        var parsed = rsingleTag.exec( data ),     //假如是单标签"<li></li>"
        scripts = !keepScripts && [];

        if ( parsed ) {    //直接创建这个元素,然后放进数组中返回
          return [ context.createElement( parsed[1] ) ];
        }

        parsed = jQuery.buildFragment( [ data ], context, scripts );  

         //如果keepScripts为false,则会传入空数组scripts ,buildFragment会判断data中是否有script,如果有就放入空数组,变成[script],没有就返回[]。如果keepScripts为true,就传入false,buildFragment不对它做改变,还是false.

        if ( scripts ) {
          jQuery( scripts ).remove();   //移除script标签
        }

        return jQuery.merge( [], parsed.childNodes );
      },//eval可以解析json字符串,任何格式的都可以,危险性提高。JSON.parse()只能解析标准的json字符串,性能好于eval。 

      parseXML: function( data ) {  //解析xml字符串为xml文档。
        var xml, tmp;
        if ( !data || typeof data !== "string" ) {
          return null;
        }

        try {
          tmp = new DOMParser();    //IE6-8使用ActiveXObject来解析
          xml = tmp.parseFromString( data , "text/xml" );

          //IE9下,如果xml字符串不是正常的xml标签,会报错。其他浏览器不会报错,会在返回的xml文档中生成parsererror节点
        } catch ( e ) {
          xml = undefined;
        }

        if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
          jQuery.error( "Invalid XML: " + data );
        }
        return xml;
      }, 

      globalEval: function( code ) {   //把局部变量变成全局变量,比如:"var a=1"。
        var script,
        indirect = eval;//eval既是关键字,又是window下的属性。直接写eval(code),浏览器会当做js关键字使用,出错。所以赋值一下,就会把eval当做window的属性。

        code = jQuery.trim( code );      //code必须为字符串形式

        if ( code ) {
          if ( code.indexOf("use strict") === 1 ) {  //严格模式下,不能使用eval.
            script = document.createElement("script");
            script.text = code;
            document.head.appendChild( script ).parentNode.removeChild( script );
          } else {
            indirect( code );
          }
        }
      },  

      camelCase: function( string ) {   //转驼峰,IE下:-ms-transform -> msTransform,而其他-moz-transform-> MozTransform,所以先把-ms-替换成ms-,这样就只会转成msTransform,m不会大写了。而其他浏览器需要大写
        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
      },

      ......

    })

    加油!

  • 相关阅读:
    java编程之:按位与运算,等运算规则
    深入理解OkHttp源码(三)——网络操作
    深入理解OkHttp源码(二)——获取响应
    深入理解OkHttp源码(一)——提交请求
    synchronized与static synchronized 的区别
    疑惑的 java.lang.AbstractMethodError: org.mybatis.spring.transaction.SpringManagedTransaction.getTimeout()L
    Spring MVC Rest服务 返回json报406错误的解决办法
    常用的几个PHP加密函数
    YII关联字段并带搜索排序功能
    linux中编译安装Apache、PHP、MySQL(上)
  • 原文地址:https://www.cnblogs.com/chaojidan/p/4154310.html
Copyright © 2020-2023  润新知