前端JS进阶五(原型)

Zepto中如何使用原型

//index.html
  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>Document</title>
  </head>
  <body>
      <p>zepto test 1</p>
      <p>zepto test 2</p>
      <p>zepto test 3</p>

      <div id="div1">
         <p>zepto test in div</p>
      </div>

      <script type="text/javascript" src="./my-zepto.js"></script>
      <script type="text/javascript">
          var $p = $('p')
          $p.css('font-size', '40px')    //CSS是原型方法
          alert($p.html())    //html是原型方法
  
          var $div1 = $('#div1')
          $div1.css('color', 'blue')    //CSS是原型方法
          alert($div1.html())    //html是原型方法
      </script>
  </body>
  </html>
Zepto使用原型源码分析
//my-zepto.js
  (function (window) {  //定义一个函数避免全局变量污染
      //空对象
      var zepto = {}
      //构造函数
      function Z(dom, selector) {
          var i, len = dom ? dom.length : 0
          for (i = 0; i < len; i++) {  //循环把dom数组赋值给this数组
              this[i] = dom[i]
          }
          this.length = len
          this.selector = selector || ''
      }

      zepto.Z = function (dom, selector) {
          return new Z(dom, selector)   //注意这里的new
      }
      
      zepto.init = function (selector) {
          //源码中这里情况很复杂 这里只针对原型来分析
          var slice = Array.prototype.slice   
          var dom = slice.call(document.querySelectorAll(selector))  //选择的dom节点数组
          return zepto.Z(dom, selector)
      }
      //Zepto里的$
      var $ = function (selector) {  //类似于函数开头
          return zepto.init(selector)
      }
      window.$ = $   //只让$变成全局变量

      $.fn = {   
          css: function (key, value) {
              alert('css')
          },
          html: function (value) {
              return '这是一个模拟的 html 函数'
          }
      }
      Z.prototype = $.fn   //构造函数Z的原型等于$.fn这一个对象
  })(window)

jQuery中如何使用原型

//index.js
  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>Document</title>
  </head>
  <body>
      <p>jquery test 1</p>
      <p>jquery test 2</p>
      <p>jquery test 3</p>

      <div id="div1">
          <p>jquery test in div</p>
      </div>

      <script type="text/javascript" src="./my-jquery.js"></script>
      <script type="text/javascript">
          var $p = $('p')
          $p.css('font-size', '40px')  //css是原型方法
          alert($p.html())  //html是原型方法
          var $div1 = $('#div1')
          $div1.css('color', 'blue')  //css是原型方法
          alert($div1.html())  //html是原型方法
      </script>
  </body>
  </html>
jQuery使用原型源码分析
//my-jquery.js
  (function (window) {
      var jQuery = function (selector) {      //jQuery里中$等同于jQuery
          return new jQuery.fn.init(selector)     //注意new关键字
      }
      //初始化 jQuery.fn
      jQuery.fn = {
          css: function (key, value) {
              alert('css')
          },
          html: function (value) {
              return 'html'
          }
      }
      //定义构造函数 与上面zepto的构造函数是一致的
      var init = jQuery.fn.init = function (selector) {
          var slice = Array.prototype.slice
          var dom = slice.call(document.querySelectorAll(selector))

          var i, len = dom ? dom.length : 0
          for (i = 0; i < len; i++) {
              this[i] = dom[i]
          }
          this.length = len
          this.selector = selector || ''
      }
      //构造函数的原型等于jQuery.fn这一个对象
      init.prototype = jQuery.fn

      window.$ = jQuery

  })(window)

原型的扩展性(插件机制)

这里思考一下

  • zepto代码中为什么要先把整个JS对象赋值给$.fn,再把$.fn赋值给Z.prototype,也就是为什么需要$.fn承担一个中介的作用?
  • jQuery代码中为什么要先把整个JS对象赋值给 jQuery.fn,再把 jQuery.fn赋值给init.prototype,也就是为什么需要 jQuery.fn承担一个中介的作用?
//因为要做插件 拓展原型
  $.fn.getNodeName = function(){
    return this[0].nodeName
  }

因为:

  • 只有$会暴露在window全局变量
  • 命名为$.fn是为了统一接口形式,能将新来的插件放在构造函数的属性中。
//插件扩展示例
  <!DOCTYPE html>
  <html>
  <head>
      <meta charset="UTF-8">
      <title>Document</title>
  </head>
  <body>
      <p>jquery test 1</p>
      <p>jquery test 2</p>
      <p>jquery test 3</p>
      <div id="div1">
          <p>jquery test in div</p>
      </div>
      <script type="text/javascript" src="./jquery-3.2.1.js"></script>
      <script type="text/javascript">
          // 插件扩展
          $.fn.getNodeName = function () {
              alert(this[0].nodeName)
          }
      </script>
      <script type="text/javascript">
          // 验证
          var $p = $('p')
          $p.getNodeName()
          var $div1 = $('#div1')
          $div1.getNodeName()
      </script>
  </body>
  </html>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,958评论 1 45
  • 在线阅读 http://interview.poetries.top[http://interview.poetr...
    前端进阶之旅阅读 115,052评论 24 450
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,964评论 2 17
  • 作为一个只有半年互联网工作经验但是实质上和运营没有很大关系的小白,之前一直抱着说主要听完老黄的课就可以找到运营工作...
    ritaNlena阅读 239评论 0 1
  • 其实,我一直让自己生活在思想的围墙里,不敢去面对,不敢冲破这堵墙。觉得生活在墙里是安全的,是不会受到伤害的。可是我...
    鹿鹿无畏阅读 699评论 2 51