原型在实际应用中的使用

问: 谈一谈原型和构造函数在实际应用中的使用?

答: 原型和构造函数在jquery和zpeto中大量的被使用。

zepto的大概的流程是这样的:

//创建一个自执行函数,避免全局变量被污染
(function(window) {
  // 声明一个zepto对象
  var zepto = {};
  function Z(dom, selector) {
    var i, len = dom ? dom.length : 0
    for(i=0;i<len;i++) {
      this[i] = dom[len];
    }
    this.length = len;
    this.selector = selector || ''
  }
  //Z方法new了一个Z的实例,说明Z是一个构造函数
  zepto.Z = function(dom, selector) {
    return new Z(dom, selector)
  }
  //init 函数将selector选中的类数组变成数组, 然后执行Z方法
  zepto.init = function (selector) {
    var slice = Array.prototype.slice;
    var dom = slice.call(document.querySelector(selector));
    return zepto.Z(dom, selector);
  }
  //$ 返回zepto初始化的方法
  var $ = function(selector) {
    return zepto.init(selector)
  }

  //给window一个$
  window.$ = $;
  $.fn = {
    css: function(key, val) {
      console.log(val)
    },
    html: function(val) {
      console.log(val)
    }
  }
  Z.prototype = $.fn
})(window)
 

jquery中的使用大致是这样的:

(function(window) {
  //初始化$
  var jQuery = function(selector) {
   return  new jQuery.fn.init(selector);
  }

  //定义fn方法

  jQuery.fn = {
    css: function(key, val) {
      alert('css')
    },
    html: function(val) {
      return 'html'
    }
  }
  var init = jQuery.fn.init = function(selector) {
    var slice = Array.prototype.slice;
    var dom = 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;
  }
  //把fn方法挂载到init的prototype上
  console.log(jQuery.fn)
  init.prototype = jQuery.fn
  //创建$方法
  window.$ = jQuery;
})(window)

 
问题: 谈一谈jquery的插件机制(讲讲原型的扩展?)
答: jquery中, 是通过$.fn.方法名来扩展插件的。这样写的好处有两个:

向全局只暴露一个变量$,而没有构造函数Z(jquery.init).
方便统一管理
代码如下:

    init.prototype = jQuery.fn
1
简单的实例:

<script type="text/javascript" src="./jquery-3.2.1.js"></script>
    <script type="text/javascript">
        // 插件扩展
        $.fn.getNodeName = function () {
            // this
            alert(this[0].nodeName)
        }
    </script>
    <script type="text/javascript">
        // 验证
        var $p = $('p')
        $p.getNodeName()
        var $div1 = $('#div1')
        $div1.getNodeName()
    </script>
 

1、原型的使用方法
(1)利用对象的动态特性给原型对象添加成员(属性、方法)
(2)直接替换原型对象:对象.prototype里面的prototype其实就是对象的一个属性,所以是可以修改替换的。如果使用过这种方式使用原型,那么会出现如下问题
        <1>在替换原型之前创建的对象的原型  和  在替换原型对象之后创建的对象的原型  不是同一个
    Person.prototype = { 
        msg:"你猜我在干啥"
    };

function Person(name,age,gender){
    this.name = name;
    this.age = age ;
    this.gender = gender;
}

Person.prototype.sayHello = function(){
    console.log("你好");
};

var p = new Person("哈哈哈",19,"male");
p.sayHello();

//替换了原型对象
Person.prototype = { //prototype其实就是Person对象的一个属性
    msg:"你猜我在干啥"
};
var p1 = new Person("12",12,"male");
console.log(p1.msg);
p1.sayHello();             //p1不能调用sayHello()
p.sayHello();                 //p能调用sayHello()

为什么p1不能调用sayHello()而p2能?
替换原型对象之前:

替换原型对象之后:


 

猜你喜欢

转载自blog.csdn.net/qq_31965515/article/details/86685827