亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

prototype.js 是如何實(shí)現(xiàn)JS的類以及類的相關(guān)屬性和作用

Snailclimb / 2180人閱讀

摘要:實(shí)現(xiàn)類的步驟第一步是使用新建類,初始化的固定函數(shù)是,不能使用其它名稱子類也是使用新建,父類放在第一個(gè)參數(shù)中,如子類中與父類的同名方法,如果需要在父類的同名方法上拓展,在需要在第一個(gè)參數(shù)中使用,然后在方法體內(nèi)使用如果需要在類的外面增加方法,可

實(shí)現(xiàn)類的步驟

第一步是使用Class.create新建類,初始化的固定函數(shù)是initialize,不能使用其它名稱

子類也是使用Class.create新建,父類放在第一個(gè)參數(shù)中,如var Cat = Class.create(Animal,{});

子類中與父類的同名方法,如果需要在父類的同名方法上拓展,在需要在第一個(gè)參數(shù)中使用$super,然后在方法體內(nèi)使用$super(args);

如果需要在類的外面增加方法,可以使用addMethods方法

// 使用 Class.create 創(chuàng)建類
    var Person = Class.create({
        // 初始函數(shù)固定為 initialize, 如果不設(shè)置,會(huì)默認(rèn)創(chuàng)建一個(gè)空函數(shù)給 initialize
        initialize:function(name) {
            this.name = name;
            this.friends = ["jack", "mark"];
        },
        getName: function(){
            console.log("My name is " + this.name);
        },
        setFriends:function(friend){
            this.friends.push(friend);
        },
        getFriends:function(){
            console.log(this.friends)
        }
    });

    // 使用 addMethods 給在類的初始構(gòu)建之外添加方法,子類可以繼承該方法
    Person.addMethods({
        getAge:function(age){
            console.log("My age is " + age);
        }
    })

    // 子類通過(guò) Class.create 創(chuàng)建類,第一個(gè)參數(shù)為父類的名字
    var Chinese = Class.create(Person,{
        // 使用 $super 為第一個(gè)參數(shù),表示當(dāng)前函數(shù)在父類的同名函數(shù)上拓展
        initialize:function($super, name, addr){
            $super(name);
            this.addr = addr;
        },
        getAddr:function(){
            console.log("My address is " + this.addr);
        }
    });

    var Japanese = Class.create(Person, {
        initialize:function($super, name){
            $super(name);
        }
    })

    // 實(shí)例化類
    var men = new Chinese("allen", "BeiJing");
    men.getName(); // My name is allen
    men.getAge(23); // My age is 23
    men.getAddr(); // My address is BeiJing

    // 以下驗(yàn)證 - 子類繼承父類的屬性,修改了之后,其他子類再次繼承父類,父類的屬性的值為何不會(huì)改變
    var allen = new Person();
    allen.getFriends(); // ["jack", "mark"]

    var women = new Japanese();
    women.setFriends("lisa");
    women.getFriends(); // ["jack", "mark", "lisa"]

    var men = new Chinese();
    men.setFriends("peter");
    men.getFriends(); //["jack", "mark", "peter"]

    var wallen = new Person();
    wallen.getFriends(); //["jack", "mark"]

JS是如何實(shí)現(xiàn)類的方法,有幾個(gè)重要的問題需要搞清楚

JS是如何創(chuàng)建類的

子類是如何實(shí)現(xiàn)繼承父類屬性和方法的

子類繼承父類的屬性,修改了之后,其他子類再次繼承父類,父類的屬性的值為何不會(huì)改變

子類和父類的同名函數(shù),在同名函數(shù)中使用$super,是如何做到在子類中共存的

如何實(shí)現(xiàn),不在類中,而是使用addMethods往類中添加方法的

下面來(lái)通過(guò)prototype.jsclass來(lái)具體分析

var Class = (function() {

  function subclass() {};
  function create() {
    // ... 
  }

  function addMethods(source) {
    // ...
  }

  // 暴露給外部的接口
  return {
    create: create,
    Methods: {
      addMethods: addMethods
    }
  };
})();

內(nèi)部實(shí)現(xiàn)其實(shí)很簡(jiǎn)單,Class是一個(gè)立即執(zhí)行函數(shù),里面只有三個(gè)函數(shù),而且subclass還是個(gè)空函數(shù)

/* Based on Alex Arnell"s inheritance implementation. */

/**
 *  Refer to Prototype"s web site for a [tutorial on classes and
 *  inheritance](http://prototypejs.org/learn/class-inheritance).
**/
var Class = (function() {

  function subclass() {};
  function create() {
    // $A 函數(shù)就是把參數(shù)轉(zhuǎn)化成數(shù)組
    var parent = null, properties = $A(arguments);
    // 如果第一個(gè)參數(shù)是函數(shù),就把他當(dāng)作父類
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      // klass 是新建的類,把傳入的參數(shù)都綁定到 klass 的 initialize 方法中
      this.initialize.apply(this, arguments);
    }

    // 把通過(guò) extend 方法,把 Class.Methods 的方法添加到 klass 中
    Object.extend(klass, Class.Methods);
    // 這里有指定 klass 的父類是哪一個(gè)
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      // 這里通過(guò)把父類的原型方法,都繼承到當(dāng)前類中
      // 通過(guò)中間變量 subclass 來(lái)傳遞 prototype 來(lái)防止由于子類的修改而導(dǎo)致父類的屬性或者方法也被修改
      subclass.prototype = parent.prototype;
      // 每次子類都會(huì)創(chuàng)建一個(gè)新的中間變量來(lái)傳遞,所以無(wú)論子類怎么修改屬性,都不會(huì)影響到父類
      klass.prototype = new subclass;
      // 把當(dāng)前類添加到父類的子類中
      parent.subclasses.push(klass);
    }

    for (var i = 0, length = properties.length; i < length; i++)
      // 前面把 addMethods 方法添加到 klass 中,這里就可以使用 addMethods 把傳入?yún)?shù)中的方法,添加到 klass 中了
      klass.addMethods(properties[i]);

    // 如果 klass 沒有初始化函數(shù),就設(shè)置一個(gè)空函數(shù)
    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    // 把 klass 的構(gòu)造函數(shù)指向自身
    klass.prototype.constructor = klass;
    return klass;
  }

  
  // source 是所有要添加進(jìn)來(lái)方法的集合
  function addMethods(source) {
    var ancestor   = this.superclass && this.superclass.prototype,
        properties = Object.keys(source);

    for (var i = 0, length = properties.length; i < length; i++) {
      // value 就是單個(gè)的方法
      var property = properties[i], value = source[property];
      // 如果參數(shù)中的第一個(gè)參數(shù)是 $super,就需要把父類的同名方法,傳遞進(jìn)來(lái)
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames()[0] == "$super") {
        // 把最初的 value 使用 method 存起來(lái)
        var method = value;
        // 繼承父類的同名方法,然后把當(dāng)前參數(shù)傳進(jìn)去
        value = (function(m) {
          return function() { return ancestor[m].apply(this, arguments); };
        })(property).wrap(method);
          // wrap 是把父類的同名方法,添加當(dāng)前類的同名方法中

        // We used to use `bind` to ensure that `toString` and `valueOf`
        // methods were called in the proper context, but now that we"re
        // relying on native bind and/or an existing polyfill, we can"t rely
        // on the nuanced behavior of whatever `bind` implementation is on
        // the page.
        //
        // MDC"s polyfill, for instance, doesn"t like binding functions that
        // haven"t got a `prototype` property defined.
        // 將 valueOf 的方法綁定到 method 中
        value.valueOf = (function(method) {
          return function() { return method.valueOf.call(method); };
        })(method);

          // 將 toString 的方法綁定到 method 中
        value.toString = (function(method) {
          return function() { return method.toString.call(method); };
        })(method);
      }
      this.prototype[property] = value;
    }

    return this;
  }

  // 暴露給外部的接口
  return {
    create: create,
    Methods: {
      addMethods: addMethods
    }
  };
})();

上面使用到的wrap函數(shù),摘抄在下面

function wrap(wrapper) {
    var __method = this;
    return function() {
      var a = update([__method.bind(this)], arguments);
      return wrapper.apply(this, a);
    }
  }

// 這里就是把 args 中的屬性,都添加到 array 中
function update(array, args) {
    var arrayLength = array.length, length = args.length;
    while (length--) array[arrayLength + length] = args[length];
    return array;
  }

JS面向?qū)ο笙盗?/p>

《javascript高級(jí)程序設(shè)計(jì)》 繼承實(shí)現(xiàn)方式

Mootools.js 是如何實(shí)現(xiàn)類,以及類的相關(guān)屬性和作用

klass 是如何實(shí)現(xiàn)JS的類以及類的相關(guān)屬性和作用

總結(jié):prototype.js,Mootools.js和klass.js 實(shí)現(xiàn)類的方法的異同與優(yōu)劣

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/84535.html

相關(guān)文章

  • klass 如何實(shí)現(xiàn)JS的類以及類的相關(guān)屬性作用

    摘要:前面介紹了和是如何實(shí)現(xiàn)類,及其類的屬性和作用的。今天介紹的就是單純的實(shí)現(xiàn)面向?qū)ο蟮膸?kù),只有多行,也照例分析吧。 前面介紹了prototype.js和Mootools.js是如何實(shí)現(xiàn)類,及其類的屬性和作用的。今天介紹的klass.js就是單純的實(shí)現(xiàn)面向?qū)ο蟮膸?kù),只有90多行,也照例分析吧。 實(shí)現(xiàn)類的步驟 第一步是使用klass新建類,初始化的固定函數(shù)是initialize,不能使用其它...

    Kross 評(píng)論0 收藏0
  • Mootools.js 如何實(shí)現(xiàn)類,以及類的相關(guān)屬性作用

    摘要:實(shí)現(xiàn)類的步驟第一步是使用新建類,初始化的固定函數(shù)是,不能使用其它名稱子類也是使用新建,父類在子類中,使用來(lái)繼承,與子類的方法名,同一級(jí)別子類中與父類的同名方法,如果需要在父類的同名方法上拓展,需要在子類的同名方法內(nèi),使用如果需要在類的外面增 實(shí)現(xiàn)類的步驟 第一步是使用new Class新建類,初始化的固定函數(shù)是initialize,不能使用其它名稱 子類也是使用new Class新建...

    gitmilk 評(píng)論0 收藏0
  • 總結(jié):prototype.js,Mootools.jsklass.js 實(shí)現(xiàn)類的方法的異同與優(yōu)劣

    摘要:構(gòu)建類的方法使用來(lái)構(gòu)建類使用來(lái)構(gòu)建類使用來(lái)構(gòu)建類繼承父類的方法使用子類方法構(gòu)建子類,繼承父類,在與父類同名的方法中,第一個(gè)參數(shù)為,方法體內(nèi)使用來(lái)拓展父類的同名方法使用正常構(gòu)建類后,第一個(gè)方法使用來(lái)繼承父類,在子類的方法體中,使用來(lái)拓展父類的 構(gòu)建類的方法 Prototype.js使用Class.create來(lái)構(gòu)建類 Mootools.js使用new Class來(lái)構(gòu)建類 klass.j...

    jeffrey_up 評(píng)論0 收藏0
  • 《javascript高級(jí)程序設(shè)計(jì)》 繼承實(shí)現(xiàn)方式

    摘要:寄生式繼承的思路與寄生構(gòu)造函數(shù)和工廠模式類似,即創(chuàng)建一個(gè)僅用于封裝繼承過(guò)程的函數(shù),該函數(shù)在內(nèi)部已某種方式來(lái)增強(qiáng)對(duì)象,最后再像真的是它做了所有工作一樣返回對(duì)象。 這篇本來(lái)應(yīng)該是作為寫JS 面向?qū)ο蟮那白啵皇亲鳛椤秊avascript高級(jí)程序設(shè)計(jì)》繼承一章的筆記 原型鏈 code 實(shí)現(xiàn) function SuperType() { this.colors = [red,blu...

    cppprimer 評(píng)論0 收藏0
  • ES7-Decorator-裝飾者模式

    摘要:裝飾者要實(shí)現(xiàn)這些相同的方法繼承自裝飾器對(duì)象創(chuàng)建具體的裝飾器,也是接收作對(duì)參數(shù)接下來(lái)我們要為每一個(gè)功能創(chuàng)建一個(gè)裝飾者對(duì)象,重寫父級(jí)方法,添加我們想要的功能。 裝飾模式 僅僅包裝現(xiàn)有的模塊,使之 更加華麗 ,并不會(huì)影響原有接口的功能 —— 好比你給手機(jī)添加一個(gè)外殼罷了,并不影響手機(jī)原有的通話、充電等功能; 使用 ES7 的 decorator ES7 中增加了一個(gè) decorator 屬性...

    zhangxiangliang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<