成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

Kross / 1347人閱讀

摘要:前面介紹了和是如何實(shí)現(xiàn)類(lèi),及其類(lèi)的屬性和作用的。今天介紹的就是單純的實(shí)現(xiàn)面向?qū)ο蟮膸?kù),只有多行,也照例分析吧。

前面介紹了prototype.jsMootools.js是如何實(shí)現(xiàn)類(lèi),及其類(lèi)的屬性和作用的。今天介紹的klass.js就是單純的實(shí)現(xiàn)面向?qū)ο蟮膸?kù),只有90多行,也照例分析吧。

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

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

子類(lèi)使用ParentClassName.extend{// 子類(lèi)方法}繼承

子類(lèi)中與父類(lèi)的同名方法,如果需要在父類(lèi)的同名方法上拓展,需要在子類(lèi)的方法體中使用this.supr(args)

如果需要在類(lèi)的外面增加方法,可以使用methods方法

// 使用 klass 創(chuàng)建類(lèi)
    var Person = klass({
        // 初始函數(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)
        }
    });

    // 使用 methods 給類(lèi)添加方法,子類(lèi)可以繼承該方法
    Person.methods({
        getAge:function(age){
            console.log("My age is " + age);
        }
    })

    // 子類(lèi)直接通過(guò) ParentClassName.extend 來(lái)繼承父類(lèi)
    var Chinese = Person.extend({
        initialize:function(name, addr){
            // 使用 this.supr(args)來(lái)使用父類(lèi)的同名函數(shù)
            this.supr(name);
            this.addr = addr;
        },
        getAddr:function(){
            console.log("My address is " + this.addr);
        }
    });

    // 子類(lèi)直接通過(guò) ParentClassName.extend 來(lái)繼承父類(lèi)
    var Japanese = Person.extend({
        initialize:function(name){
            this.supr(name);
        }
    })

    // 實(shí)例化類(lèi)
    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)證 - 子類(lèi)繼承父類(lèi)的屬性,修改了之后,其他子類(lèi)再次繼承父類(lèi),父類(lèi)的屬性的值為何不會(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)類(lèi)的方法,有幾個(gè)重要的問(wèn)題需要搞清楚

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

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

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

子類(lèi)和父類(lèi)的同名函數(shù),在同名函數(shù)中使用$supr,是如何做到在子類(lèi)中共存的
如何實(shí)現(xiàn),不在類(lèi)中,而是使用methods往類(lèi)中添加方法的

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

!function (name, context, definition) {
  if (typeof define == "function") define(definition)
  else if (typeof module != "undefined") module.exports = definition()
  else context[name] = definition()
}("klass", this, function () {
  var context = this
    , f = "function"
      // 是否使用了 supr 來(lái)調(diào)用父類(lèi)的同名函數(shù)
    , fnTest = /xyz/.test(function () {xyz}) ? /supr/ : /.*/
    , proto = "prototype"

    // o 為創(chuàng)建類(lèi)時(shí),類(lèi)的方法
  function klass(o) {
    return extend.call(isFn(o) ? o : function () {}, o, 1)
  }

  // 判斷對(duì)象是否是函數(shù)
  function isFn(o) {
    return typeof o === f
  }

  // 將父類(lèi)的方法/屬性,附加到子類(lèi)中
  function wrap(k, fn, supr) {
    return function () {
      var tmp = this.supr
        // 當(dāng)前函數(shù)的 supr,就是父類(lèi)的同名函數(shù)
      this.supr = supr[proto][k]
      var undef = {}.fabricatedUndefined
      var ret = undef
      try {
        // this 是當(dāng)前類(lèi),fn 是父類(lèi)的函數(shù),fn 的上下文是綁定在當(dāng)前類(lèi)中,所以就等于父類(lèi)的方法就繼承到子類(lèi)中了
        ret = fn.apply(this, arguments)
      } finally {
        this.supr = tmp
      }
      return ret
    }
  }

  // 子類(lèi)繼承父類(lèi)的屬性,如果有同名函數(shù),就使用 wrap 方法處理,如果沒(méi)有,就完全繼承該屬性
  // what : child; o : parent; supr: parentClass
  function process(what, o, supr) {
    for (var k in o) {
      if (o.hasOwnProperty(k)) {
        what[k] = isFn(o[k])
          && isFn(supr[proto][k])
          && fnTest.test(o[k])
          ? wrap(k, o[k], supr) : o[k]
      }
    }
  }

  // 實(shí)現(xiàn)繼承的主函數(shù), o創(chuàng)建類(lèi)時(shí)的所有函數(shù),fromSub 為1,不明白為什么不把fromSub設(shè)置為true/false
  function extend(o, fromSub) {
    // must redefine noop each time so it doesn"t inherit from previous arbitrary classes
    function noop() {}
    noop[proto] = this[proto]
    var supr = this
      , prototype = new noop()
      , isFunction = isFn(o)
      , _constructor = isFunction ? o : this
      , _methods = isFunction ? {} : o
    function fn() {
      // 如果當(dāng)前類(lèi)設(shè)置類(lèi) initialize 函數(shù),就把傳給當(dāng)前類(lèi)的參數(shù)傳遞給該函數(shù)
      if (this.initialize) this.initialize.apply(this, arguments)
      else {
        // 如果沒(méi)有設(shè)置 initialize ,傳入類(lèi)的參數(shù)也能被其它函數(shù)使用
        fromSub || isFunction && supr.apply(this, arguments)
        _constructor.apply(this, arguments)
      }
    }

    // 使用 methods 添加方法到當(dāng)前類(lèi),o 為使用 methods 內(nèi)的方法
    fn.methods = function (o) {
      process(prototype, o, supr)
      fn[proto] = prototype
      return this
    }

    // 指定 fn 的 constructor
    fn.methods.call(fn, _methods).prototype.constructor = fn

    // 使用 ParentClassName.extend 來(lái)實(shí)現(xiàn)繼承時(shí)候的
    fn.extend = arguments.callee
      // 使用 implement 來(lái)重寫(xiě)父類(lèi)的方法或者拓展父類(lèi)的方法
      // o : 函數(shù)名 ; optFn : 函數(shù)
    fn[proto].implement = fn.statics = function (o, optFn) {
      o = typeof o == "string" ? (function () {
        var obj = {}
        obj[o] = optFn
        return obj
      }()) : o
      // 使用 process 把 implement 中的函數(shù)添加到當(dāng)前類(lèi)中
      process(this, o, supr)
      return this
    }

    return fn
  }

  return klass
});

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

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

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

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

    gitmilk 評(píng)論0 收藏0
  • JavaScript MVC 學(xué)習(xí)筆記(四)類(lèi)的使用(下)

    摘要:基于函數(shù)進(jìn)行調(diào)用的,用來(lái)確保函數(shù)是在指定的值所在的上下文中調(diào)用的。添加私有函數(shù)目前上面為類(lèi)庫(kù)添加的屬性都是公開(kāi)的,可以被隨時(shí)修改。以基于的富應(yīng)用開(kāi)發(fā)為主要學(xué)習(xí)資料。 控制類(lèi)庫(kù)的作用域 在類(lèi)和實(shí)例中都添加proxy函數(shù),可以在事件處理程序之外處理函數(shù)的時(shí)候保持類(lèi)的作用域。下面是不用proxy的辦法: var Class = function(parent){ var klas...

    Rango 評(píng)論0 收藏0
  • JavaScript MVC 學(xué)習(xí)筆記(三)類(lèi)的使用(中)

    摘要:實(shí)際上,可以將其理解為某種形式的繼承。如果上下文是,則使用全局對(duì)象代替。例如的第個(gè)參數(shù)是上下文,后續(xù)是實(shí)際傳入的參數(shù)序列中允許更換上下文是為了共享狀態(tài),尤其是在事件回調(diào)中。 公開(kāi)記錄學(xué)習(xí)JS MVC,不知道能堅(jiān)持多久= =。以《基于MVC的JavaScript web富應(yīng)用開(kāi)發(fā)》為主要學(xué)習(xí)資料。接上一篇類(lèi)的學(xué)習(xí),發(fā)現(xiàn)實(shí)在是看暈了,有些例子是能看懂在干嘛,但是不知道為什么這樣做,有的甚至...

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

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

0條評(píng)論

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