<small id='XUdV7'></small><noframes id='XUdV7'>

<legend id='XUdV7'><style id='XUdV7'><dir id='XUdV7'><q id='XUdV7'></q></dir></style></legend>
    <bdo id='XUdV7'></bdo><ul id='XUdV7'></ul>
<i id='XUdV7'><tr id='XUdV7'><dt id='XUdV7'><q id='XUdV7'><span id='XUdV7'><b id='XUdV7'><form id='XUdV7'><ins id='XUdV7'></ins><ul id='XUdV7'></ul><sub id='XUdV7'></sub></form><legend id='XUdV7'></legend><bdo id='XUdV7'><pre id='XUdV7'><center id='XUdV7'></center></pre></bdo></b><th id='XUdV7'></th></span></q></dt></tr></i><div id='XUdV7'><tfoot id='XUdV7'></tfoot><dl id='XUdV7'><fieldset id='XUdV7'></fieldset></dl></div>
  • <tfoot id='XUdV7'></tfoot>

      1. 解析John Resig Simple JavaScript Inheritance代码

        时间:2023-12-09
          <bdo id='eCBJk'></bdo><ul id='eCBJk'></ul>

          <tfoot id='eCBJk'></tfoot>
        • <i id='eCBJk'><tr id='eCBJk'><dt id='eCBJk'><q id='eCBJk'><span id='eCBJk'><b id='eCBJk'><form id='eCBJk'><ins id='eCBJk'></ins><ul id='eCBJk'></ul><sub id='eCBJk'></sub></form><legend id='eCBJk'></legend><bdo id='eCBJk'><pre id='eCBJk'><center id='eCBJk'></center></pre></bdo></b><th id='eCBJk'></th></span></q></dt></tr></i><div id='eCBJk'><tfoot id='eCBJk'></tfoot><dl id='eCBJk'><fieldset id='eCBJk'></fieldset></dl></div>

          <small id='eCBJk'></small><noframes id='eCBJk'>

            <legend id='eCBJk'><style id='eCBJk'><dir id='eCBJk'><q id='eCBJk'></q></dir></style></legend>

                  <tbody id='eCBJk'></tbody>
                1. 解析 John Resig 在 Simple JavaScript Inheritance 代码的思路可以分为以下几个部分:

                  简介

                  这是 John Resig 在 2008 年发布的一个 JavaScript 类继承的库,用来实现类的继承。

                  源代码及解析

                  下面我们来逐行分析源代码实现:

                  首先,定义了一个匿名函数,并将其赋值给 Class 变量。

                  var Class = (function() {
                      // ...
                  })();
                  

                  这里利用了函数声明的特性,定义了一个 IIFE,返回一个对象。

                  1. Fn.prototype.extend

                  接下来就是对象的方法,其中,最重要的就是 extend 方法,这个方法有两个参数,第一个是一个对象,表示新的类的原型对象,第二个是一个对象,表示新的类的静态属性和方法。

                  // 添加方法和静态属性
                  Function.prototype.extend = function(prop) {
                    var _super = this.prototype;
                  
                    function F() {};
                    F.prototype = _super;
                  
                    var prototype = new F();
                  
                    for(var name in prop) {
                      if(typeof prop[name] === "function" &&
                         typeof _super[name] === "function" &&
                         fnTest.test(prop[name])) {
                  
                        prototype[name] = (function(name, fn) {
                          return function() {
                            var tmp = this._super;
                            this._super = _super[name];
                            var ret = fn.apply(this, arguments);
                            this._super = tmp;
                            return ret;
                          };
                        })(name, prop[name]);
                  
                      } else {
                        prototype[name] = prop[name];
                      }
                    }
                  
                    function Class() {
                      if (this.init) {
                        this.init.apply(this, arguments);
                      }
                    }
                  
                    Class.prototype = prototype;
                    Class.constructor = Class;
                    Class.extend = arguments.callee;
                  
                    return Class;
                  };
                  

                  在这个方法的内部中,核心部分就是以下这段代码:

                  var _super = this.prototype;
                  function F() {};
                  F.prototype = _super;
                  var prototype = new F();
                  

                  这里定义了一个代理函数 F,这个函数的作用是一个中间代理层,可以用来保存原型对象 _super 的引用,从而避免对父类对象的修改。

                  接下来,将代理函数 F 的原型属性指向当前对象的原型属性,这样代理函数 F 就成为了一个新的对象,这个新的对象有原型属性继承自当前对象。

                  接着定义一个 for 循环,遍历新的类的原型对象上的属性,将方法保存至新的原型对象上。

                  其中,最重要的部分在于这样的一个条件判断:

                  typeof prop[name] === "function" &&
                  typeof _super[name] === "function" &&
                  fnTest.test(prop[name])
                  

                  如果当前对象和父类对象上都拥有相同名称的方法,并且这个方法符合正则表达式 fnTest 规定的格式,则使用 closure 的思想实现闭包函数。

                  这里 closure 函数在 arguments 对象中做了一个小的修改,简单来说就是是利用 arguments 对象保存 this 的引用,并在函数返回的时候计算出方法的返回值。

                  对于非方法的属性,直接将属性保存到新的原型对象上。

                  最后,定义并返回一个改写过的函数 Class,用来定义新的类。

                  在 Class 中,还增加了一个新的方法 init,用来在对象创建时初始化对象的属性。

                  2. _super 属性

                  另外一个重要的功能就是函数中的 _super 属性,这个属性用来在子类中调用父类中相同名称的方法。

                  var _super = this._super || function() {};
                  

                  这个属性也是利用了 closure 函数的思想,每一次将 _super 模拟为当前方法的上一个版本,避免对父类对象进行操作。

                  3. 对象的创建

                  Class 这个对象是通过原型属性来定义的,因此可以用 new 关键字来创建新的对象。在对象创建的时候,可以传递参数给 init 方法初始化对象的属性。

                  示例说明

                  示例 1:

                  // 父类
                  var Person = Class.extend({
                    init: function(name, age) {
                      this.name = name;
                      this.age = age;
                    },
                    sayName: function() {
                      console.log("name: " + this.name);
                    },
                    sayAge: function() {
                      console.log("age: " + this.age);
                    }
                  });
                  
                  // 子类
                  var Student = Person.extend({
                    init: function(name, age, stuNo) {
                      this._super(name, age);
                      this.stuNo = stuNo;
                    },
                    sayStuNo: function() {
                      console.log("student number: " + this.stuNo);
                    }
                  });
                  
                  // 创建父类对象
                  var p = new Person("Tom", 20);
                  console.log(p); // Person {name: "Tom", age: 20}
                  
                  // 创建子类对象
                  var s = new Student("Jhon", 18, 20210001);
                  console.log(s); // Student {name: "Jhon", age: 18, stuNo: 20210001}
                  
                  s.sayName(); // name: Jhon
                  s.sayAge(); // age: 18
                  s.sayStuNo(); // student number: 20210001
                  

                  以上是一个简单 class 继承的示例,通过相同的名称的方法实现了类的继承。

                  示例 2:

                  var Animal = Class.extend({
                    makeSound: function() {
                      console.log("Animal sound...");
                    }
                  });
                  
                  var Cat = Animal.extend({
                    makeSound: function() {
                      console.log("Mew...");
                      this._super();
                    }
                  });
                  
                  var cat = new Cat();
                  cat.makeSound(); // Mew... \n Animal sound...
                  

                  这是一个更加直观的 _super 方法的使用示例。通过先在子类中重写方法,再显示调用父类的方法实现了在子类方法中调用父类方法的使用。

                  上一篇:js实现图片切换(动画版) 下一篇:webpack output.library的16 种取值方法示例

                  相关文章

                    • <bdo id='4pGlL'></bdo><ul id='4pGlL'></ul>

                    <small id='4pGlL'></small><noframes id='4pGlL'>

                    <i id='4pGlL'><tr id='4pGlL'><dt id='4pGlL'><q id='4pGlL'><span id='4pGlL'><b id='4pGlL'><form id='4pGlL'><ins id='4pGlL'></ins><ul id='4pGlL'></ul><sub id='4pGlL'></sub></form><legend id='4pGlL'></legend><bdo id='4pGlL'><pre id='4pGlL'><center id='4pGlL'></center></pre></bdo></b><th id='4pGlL'></th></span></q></dt></tr></i><div id='4pGlL'><tfoot id='4pGlL'></tfoot><dl id='4pGlL'><fieldset id='4pGlL'></fieldset></dl></div>
                      <tfoot id='4pGlL'></tfoot>
                      <legend id='4pGlL'><style id='4pGlL'><dir id='4pGlL'><q id='4pGlL'></q></dir></style></legend>