javascript 继承学习心得总结

看了不少js继承的东西也该总结总结了。
先说一下大概的理解,有不对的还望指正,也好更正一下三观。另外说明下,下面的例子并非原创基本就是改了个变量名啥的,有的甚至直接拿过来用的。

js继承是用来干啥的:

首先说js没有真正的跟其他面向对象的语言一样概念的继承,js里边所说的继承是指模拟继承。
具体js继承是干啥呢,刚开始做前端的时候我是用来面试的(最早写些小效果的时候基本用不到,为啥要看呢,因为面试官很爱问这个问题啊),所以就看看大概的,面试时候能说个大概,在这个问题上算是面试党了。后来跟着慢慢的实际上虽然概念不是很明确也用到一些。
真正是用来干啥的呢,主要是用来复用我们之前写过的代码。比如写过一个功能,一个对象,或者用别人写的东西,我们要自己加点儿什么,总不能改人家的东西吧,直接继承过来用一下就好了,这才是继承的真正用途。

js继承怎么实现:
先不上代码,先说说想法。其实继承呢就是想办法把其他对象(js里边一切皆对象哈)的属性或者方法搞到我们自己的对象上,让我们自己的这个对象可以用。这也就达到复用的目的了。
目的搞明白了,下面就是实现手段了。
根据js的特性,实现无非就是以下几种方法的其中一种或者组合使用。

1、构造函数,js好像没有严格的构造函数的定义,但是可以用new来创建新的对象。构造函数据说也是严格的面向对象的语言实现继承的方法,那么js当然可以模拟一下了,所以学过oop语言的人们会最先想到这个。

2、利用函数原型,利用原型链把两个对象链接起来,因为js原型链是比较独特所以想到这个也是很容易的。
原型也分几种,就是把什么作为继承对象的原型,被继承对象的原型或者被继承对象的实例,或者直接被继承者。这几种作为继承对象的原型得到的继承效果是不一样的。

3、复制属性和方法,把被继承对象的属性或者方法统统复制克隆过来变成我们自己对象的属性和方法就好了啊,我们就可以无比顺畅的用了。当然这个还分浅复制和深度复制两种情况。

4、利用call和apply这两个方法,这两个方法比较神奇,可以改变函数执行的上下文(this),所以利用这两个方法也可以实现对被继承对象的方法的继承复用。
 
总的来js实现继承的途径大概就是这些,千变万化的实现方法都是从这几种方法的基础上组合升级完善出来的,为毛大多数要组合使用呢,当然是因为使用单个方法实现的效果不太理想啊。当然可以根据自己项目中实际的需求选择使用哪种方式,只要满足自己的需求并没有说必须使用哪种方法去实现。就像说从北京去石家庄,最快当然是飞机啦。但是如果离机场远,算上到机场,从机场去市里,整体算下来还不如高铁快,那就可以做高铁。又比如自己有车可以开车,想要挑战一下还可以骑自行车,这个根据自己的实际情况来选就可以。

代码实现,下面结合代码说说上面的几种实现方法,有些是从其他地方摘来的,加点儿注释啥的。

看了不少js继承的东西也该总结总结了。
先说一下大概的理解,有不对的还望指正,也好更正一下三观。另外说明下,下面的例子并非原创基本就是改了个变量名啥的,有的甚至直接拿过来用的。

js继承是用来干啥的:

首先说js没有真正的跟其他面向对象的语言一样概念的继承,js里边所说的继承是指模拟继承。
具体js继承是干啥呢,刚开始做前端的时候我是用来面试的(最早写些小效果的时候基本用不到,为啥要看呢,因为面试官很爱问这个问题啊),所以就看看大概的,面试时候能说个大概,在这个问题上算是面试党了。后来跟着慢慢的实际上虽然概念不是很明确也用到一些。
真正是用来干啥的呢,主要是用来复用我们之前写过的代码。比如写过一个功能,一个对象,或者用别人写的东西,我们要自己加点儿什么,总不能改人家的东西吧,直接继承过来用一下就好了,这才是继承的真正用途。

js继承怎么实现:
先不上代码,先说说想法。其实继承呢就是想办法把其他对象(js里边一切皆对象哈)的属性或者方法搞到我们自己的对象上,让我们自己的这个对象可以用。这也就达到复用的目的了。
目的搞明白了,下面就是实现手段了。
根据js的特性,实现无非就是以下几种方法的其中一种或者组合使用。

1、构造函数,js好像没有严格的构造函数的定义,但是可以用new来创建新的对象。构造函数据说也是严格的面向对象的语言实现继承的方法,那么js当然可以模拟一下了,所以学过oop语言的人们会最先想到这个。

2、利用函数原型,利用原型链把两个对象链接起来,因为js原型链是比较独特所以想到这个也是很容易的。
原型也分几种,就是把什么作为继承对象的原型,被继承对象的原型或者被继承对象的实例,或者直接被继承者。这几种作为继承对象的原型得到的继承效果是不一样的。

3、复制属性和方法,把被继承对象的属性或者方法统统复制克隆过来变成我们自己对象的属性和方法就好了啊,我们就可以无比顺畅的用了。当然这个还分浅复制和深度复制两种情况。

4、利用call和apply这两个方法,这两个方法比较神奇,可以改变函数执行的上下文(this),所以利用这两个方法也可以实现对被继承对象的方法的继承复用。
 
总的来js实现继承的途径大概就是这些,千变万化的实现方法都是从这几种方法的基础上组合升级完善出来的,为毛大多数要组合使用呢,当然是因为使用单个方法实现的效果不太理想啊。当然可以根据自己项目中实际的需求选择使用哪种方式,只要满足自己的需求并没有说必须使用哪种方法去实现。就像说从北京去石家庄,最快当然是飞机啦。但是如果离机场远,算上到机场,从机场去市里,整体算下来还不如高铁快,那就可以做高铁。又比如自己有车可以开车,想要挑战一下还可以骑自行车,这个根据自己的实际情况来选就可以。

代码实现,下面结合代码说说上面的几种实现方法,有些是从其他地方摘来的,加点儿注释啥的。

一、构造函数实现(借用构造函数):

function Super(arg){
      this.arr1 = "I'm super "+arg;
      this.show = function(){
        alert(this.arr1);
      }
    }

    Super.prototype.say = function(){
      alert(this.arr1);
    }

    function suber(arg){
      Super.apply(this, arguments); //在suber的上下文中运行super
    }

    var sub =new suber("suber");
    var sub2 = new suber("suber1");

    console.log(sub.arr1); //I'm super suber
    console.log(sub.show); //function (){ alert(this.arr1);}
    console.log(sub.say); //undefined
    console.log(sub.show === sub2.show); //false

哎呀,发现sub.say是undefined,这说明它没有被继承过来啊,下边两个对象sub,sub2的show不相等,说明两个函数指向了两个不同的对象,也就是说被复制了两份出来。

所以这个方法实现继承的话原型对象上的属性和方法没有被继承过来,Super上的属性和方法为每个new出来的对象分别复制一份。
所以单单使用这个方法来实现继承还是不妥啊,因为原型上的方法都没有被继承过来啊。于是大神们就想到了原型继承

二、原型继承:

function Super(arg){
      this.arr1 = "I'm super "+arg;
      this.show = function(){
        alert(this.arr1);
      }
    }

    Super.prototype.say = function(){
      alert(this.arr1);
    }

    function suber(arg){}

    suber.prototype = new Super();

    var sub = new suber("suber1");
    var sub2 = new suber("suber2");

    console.log(sub.arr1); //I'm super undefined
    console.log(sub.show); //function (){ alert(this.arr1);}
    console.log(sub.say); //function (){ alert(this.arr1);}
    console.log(sub.show === sub2.show);  //true;
    console.log(sub.say === sub2.say);  //true;

这次是arr1继承过来了,但是参数没有添加进来,是undefined,所以这个方法子类声明时候这个参数传进来付类继承过来的这个属性没法收到。其他的都还算正常。show和say都继承过来了。但是有一点儿需要注意,say是通过super的原型对象继承过来的,而show是新建super对象实例时实例的属性。

那么怎么实现参数传输又能把原型里边的东东继承过来呢,当然上边两种方法组合一下就好了啊,于是前辈们又发明了下面这种方法

三、组合继承(借用构造函数并设置原型):

function Super(arg){
      this.arr1 = "I'm super "+arg;
      this.show = function(){
        alert(this.arr1);
      }
    }

    Super.prototype.say = function(){
      alert(this.arr1);
    }

    function suber(arg){
      Super.apply(this, arguments);
    }

    suber.prototype = new Super();

    var sub = new suber("suber1");
    var sub2 = new suber("suber2");

    console.log(sub.arr1); //I'm super suber1
    console.log(sub.show); //function (){ alert(this.arr1);}
    console.log(sub.say); //function (){ alert(this.arr1);}
    console.log(sub.show === sub2.show);  //false;
    console.log(sub.say === sub2.say);  //true;

这次几乎完美了,但是可以发现sub.show 和sub2.show并不相等啊,这是为啥呢,因为apply这个地方使得show成为了suber的自己的属性,那么就吧suber原型里的show(Super的当做suber原型对象的实例对象的show)给覆盖了,所以又变成每次复制一个,当然这个地方没有办法避免啊。为了不产生这种多余的开消这种可以共用的函数可以多放到原型对象里边。
因为suber的构造里边的调用,和给suber原型对象赋值时候的调用导致Super被调用了两次,那么每次new suber对象时候就调用了两次Super,调用两次就会产生两个实例对象,需要消耗多余的资源了。

于是前辈们为了解决这个问题又开了开脑洞,开发出来下面这种方法。

四、寄生组合继承:
该方法跟方法三最主要的不同就是把父类原型赋给了子类原型而不是父类示例,看例子

function Super(arg){
  this.arr1 = "I'm super "+arg;

}

Super.prototype.show = function(){ //这个方法放到了原型对象上。
    alert(this.arr1);
  }
Super.prototype.say = function(){
  alert(this.arr1);
}

function suber(arg){
  Super.apply(this, arguments);
}

/*inherit函数的作用,使用一个新的空函数,来切断父类对象的原型对象与子类原型对象的直接联系,而是通过这个空构造的实例对象实现继承,这样可以避免更改子类原型的属性或者方法而影响了父类原型对象的属性或者方法。*/

function inherit(obj){
  function F(){}
  F.prototype = obj;
  return new F();
}

suber.prototype = inherit(Super.prototype);

var sub = new suber("suber1");
var sub2 = new suber("suber2");

console.log(sub.arr1); //I'm super suber1
console.log(sub.show); //function (){ alert(this.arr1);}
console.log(sub.say); //function (){ alert(this.arr1);}
console.log(sub.show === sub2.show);  //true;
console.log(sub.say === sub2.say);  //true;

好了,这样就把三方法的弊端干掉了,这个可以完美的使用了吧。

五、复制属性实现

拷贝我们可以写一个拷贝函数来实现。

function extend(Super,suber){
  suber = suber || {};
  for(var i in Super){
    if(Super.hasOwnProperty(i)){
      suber[i] = Super[i];
    }
   }
  return suber;
}

var parent = {
  name:"dad",
  num:[1,2,3],
  say:function(){alert("dad");}
}

var child = {
  age:5,
  sex:"boy"
};

child = extend(parent, child);

//以下测试
console.log(child); /*{
             age:5,
             sex:"boy",
             name:"dad",
             num:[1,2,3],
             say:function(){alert("dad");}
            }*/
console.log(child.say === parent.say); //true
console.log(child.num === parent.num); //true

复制成功,那么child成功继承了parent的一些属性,但是后面两个测试发现他们是相等的,就表明了他们在公用同一个数组,同一个函数,函数这个可以,但是数组这个就有问题了,如果一个chiild改变了数组,几个被继承对象的数组也跟着变了,这就不给力了啊。
为什么会发生这种情况呢,js里边对象存储的是指针,然后这个指针指向这个值,我们在这复制的实际是指向该对象的指针的值,所以继承对象和被继承对象都指向了同一个对象,接下来看看如何使用深度复制来解决这个问题。

深度复制对象属性:

function extenddeep(Super, suber){
      var tostr = Object.prototype.toString, astr = "[object Array]";
      suber = suber || {};

      for(var i in Super){
        if(Super.hasOwnProperty(i)){
          if(typeof Super[i] === "object"){
            suber[i] = (tostr.call(Super[i]) == astr) ? [] : {};
            extenddeep(Super[i],suber[i]);
          }else {
            suber[i] = Super[i];
          }
        }
      }

      return suber;
    }

    var parent = {
      name:"papa",
      num:[1,2,3],
      say:function(){alert("I'm father of my son!");}
    }

    var child = {
      name:"jone",
      sex:"boy",
    }

    var kid = extenddeep(parent, child);

    console.log(kid);  // {name: "papa"
                num: Array[3]
                say: ()
                sex: "boy"
              // }

    console.log(kid.say === parent.say); //true
    console.log(kid.num === parent.num);  //false
    console.log(kid.name); //papa

好了,深度复制完毕,但似有木有发现问题,name是parent的,也就是说如果继承对象有和被继承对象一样的属性名的属性如果不做处理就会被替换掉。那么我们可以做一下处理,先声明一个属性,保存parent里的东西,剩下的的当然就是child自己的东西了,最后再把属性给child对象就可以了。

六、利用call和apply这两个方法(借用方法)。
这个就是通过call和apply来复用其他对象的方法,达到复用的目的。

var one = {
      name:"object",
      say: function(greet){
        return greet + ', ' + this.name;
      }
    }

    var tow = {
      name:"two"
    }

    one.say.call(tow, "hi");  //hi, two

这个就是借用了,好了,下课。

好吧,好吧,其实这里边还有其他东西要看。可以借用并不“带表”可以随便把某个方法赋值给谁然后跟没发生什么似的继续用。所以我们平时使用借用时要注意一下上下文,下面看下那些容易出错的地方。

//赋值给一个变量时候上下文会变化
    var say = one.say;
    console.log(say('hoho')); // "hoho, undefined"

    //作为回调函数时也会发生变化
    var yetother = {
      name:"yetother obj",
      method:function(callback){
        return callback("Hola");
      }
    }

    console.log(yetother.method(one.say)); //"Hola, "

神马意思呢,就是this.name是undefined,当one.say赋值给say是,实际上是say存储了指向函数对象的指针,say这个变量明显又是全局变量的一个属性,那么它运行的时候实际的上下文就变成了windows了,当然这个时候name就变成undefined了。回调这个也是一样,return 的是函数运行的结果。如果我们事先设置 windows.name="windows" 那么得到的结果就变成了 "hoho, windows" 和"Hola, windows" 了。

function bind(o, m){
      return function(){
        return m.apply(o, [].slice.call(arguments));
      }
    }

    var othersay = bind(yetother, one.say);

    othersay("Hola"); //"Hola, yetother obj"

通过apply可以改变方法执行的上下文,那么我们构建一个函数来实现这样一个功能,通过使用方法调用实现上下文的改变,这样就不会出现上下文不是我们期望的上下文的情况了。

//这段是直接复制过来的。
    // ECMAScript 5给Function.prototype添加了一个bind()方法,以便很容易使用apply()和call()。

      if (typeof Function.prototype.bind === 'undefined') {
        Function.prototype.bind = function (thisArg) {
          var fn = this,
      slice = Array.prototype.slice,
      args = slice.call(arguments, 1);
          return function () {
            return fn.apply(thisArg, args.concat(slice.call(arguments)));
          };
        };
      }

      var twosay2 = one.say.bind(two);
      console.log(twosay2('Bonjour')); // "Bonjour, another object"

      var twosay3 = one.say.bind(two, 'Enchanté');
      console.log(twosay3()); // "Enchanté, another object"

介绍完了,该说说自己的疑惑了,当复制属性方法遇到的被继承对象里边存在方法,如何单独复制出来呢,现在的是直接共用了,因为毕竟方法一般不会经常改动。求解答?

下面是转载过来的jQuery的extend方法,好像也没有特殊处理函数这块,继承完了两个函数也是共用的。

$.extend源码

jQuery.extend = jQuery.fn.extend = function() {
          var options, name, src, copy, copyIsArray, clone,
             target = arguments[0] || {},
             i = 1,
             length = arguments.length,
             deep = false ;

          // Handle a deep copy situation
          //如果第一个参数是boolean类型
          //修正参数,将第二个参数作为target
          if ( typeof target === "boolean" ) {
             deep = target;

              // skip the boolean and the target
             target = arguments[ i ] || {};
              //i++是为了后续 i === length的判断
             i++;
          }

          // Handle case when target is a string or something (possible in deep copy)
          //如果目标既不是对象也不是方法(例如给基本类型扩展属性方法和属性不会报错但是是无用的),修正target为 js对象
          if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
             target = {};
          }

          // extend jQuery itself if only one argument is passed
          //如果只有一个参数,修正对象为JQuery函数或JQuery对象
          if ( i === length ) {
             target = this ;
              //修正target所在位置,后面的都是要添加给target的对象
             i--;
          }

          for ( ; i < length; i++ ) {
              // Only deal with non-null/undefined values
              if ( (options = arguments[ i ]) != null ) {
                 // Extend the base object
                 for ( name in options ) {
                    src = target[ name ];
                    copy = options[ name ];

                    // Prevent never-ending loop
                    //如果target和copy是同一个对象,略过,防止自己的属性引用了本身对象导致的循环引用,以致GC无法回收
                    if ( target === copy ) {
                        continue ;
                    }

                    // Recurse if we're merging plain objects or arrays
                    //如果是deep为true,并且要添加给target的copy为对象获数组
                    if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                        if ( copyIsArray ) {
                           copyIsArray = false ;
                           clone = src && jQuery.isArray(src) ? src : [];

                       } else {
                           clone = src && jQuery.isPlainObject(src) ? src : {};
                       }

                        // Never move original objects, clone them
                        //很巧妙 ,用一个递归,实现引用对象的深克隆,递归的返回条件是属性石基本类型,基本类型都是深克隆
                       target[ name ] = jQuery.extend( deep, clone, copy );

                    // Don't bring in undefined values
                    } else if ( copy !== undefined ) {
                        //浅克隆
                       target[ name ] = copy;
                    }
                 }
             }
          }

          // Return the modified object
          return target;
      };

以上这篇javascript 继承学习心得总结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结

    这是一篇关于javascript模块化AMD,CMD,CommonJS的学习总结,作为记录也给同样对三种方式有疑问的童鞋们,有不对或者偏差之处,望各位大神指出,不胜感激. 本篇默认读者大概知道require,seajs的用法(AMD,CMD用法),所以没有加入使用语法. 1.为何而生: 这三个规范都是为javascript模块化加载而生的,都是在用到或者预计要用到某些模块时候加载该模块,使得大量的系统巨大的庞杂的代码得以很好的组织和管理.模块化使得我们在使用和管理代码的时候不那么混乱,而且也方便

  • JavaScript 对象深入学习总结(经典)

    一.概述 对象是一种复合值,它将很多值(原始值或其他对象)聚合在一起,可通过属性名访问这些值.而属性名可以是包含空字符串在内的任意字符串. JavaScript对象也可以称作一种数据结构,正如我们经常听说的"散列(hash)"."散列表(hashtable)"."字典 (dictionary)"."关联数组(associative array)". JavaScript中对象可以分为三类: ①内置对象,例如数组.函数.日期等:

  • js学习阶段总结(必看篇)

    typeof操作符:返回字符串,可能是"undefined","boolean"," string","number","object","function"中的一种,所以不能判断数组. NaN(Not a Number):用法NaN(val)如果val能被转化成一个数就返回false,否则返回true. parseInt(val,way)其中way可以是2,4...就是要按照这个进制来

  • JavaScript函数学习总结以及相关的编程习惯指南

    null 和 undefined Undefined相当于一个变量并没有明确的被赋值(是否被赋值, 可能无心忽略, 逻辑问题) JS的怪异之处就在于undefined真的是一个可以使用的值. > var foo; > foo undefined 同理,当缺失参数时 JavaScript 会分配一个 undefined: > function id(x) { return x } > id() undefined a = 1; a !== undefined // true a =

  • javascript学习总结之js使用技巧

    1 假如浏览器不支持JavaScript怎么办? a.为什么浏览器会不支持?大部分浏览器都有禁用脚本的功能,例如chrome. b.在js被禁用的情况下要保证网页仍能实现它的核心功能(关键的用户需求) 例子:在一个新窗口里打开链接,可以使用BOM的open()方法 function popUp(winURL) { window.open(winURL, "popup", "width=,height="); } 具体的js实现有以下几个方案: 方案一:使用javas

  • JavaScript学习总结之JS、AJAX应用

    1.AJAX 简介 AJAX(音译为:阿贾克斯) = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术,也就是在无需重新加载整个网页的情况下,能够更新部分网页的技术.AJAX 不是新的编程语言,而是一种使用现有标准的新方法,是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新,传统的

  • javascript 继承学习心得总结

    看了不少js继承的东西也该总结总结了. 先说一下大概的理解,有不对的还望指正,也好更正一下三观.另外说明下,下面的例子并非原创基本就是改了个变量名啥的,有的甚至直接拿过来用的. js继承是用来干啥的: 首先说js没有真正的跟其他面向对象的语言一样概念的继承,js里边所说的继承是指模拟继承. 具体js继承是干啥呢,刚开始做前端的时候我是用来面试的(最早写些小效果的时候基本用不到,为啥要看呢,因为面试官很爱问这个问题啊),所以就看看大概的,面试时候能说个大概,在这个问题上算是面试党了.后来跟着慢慢的

  • JavaScript继承学习笔记【新手必看】

    JavaScript作为一个面向对象语言(JS是基于对象的),可以实现继承是必不可少的,但是由于本身并没有类的概念,所以不会像真正的面向对象编程语言通过类实现继承,但可以通过其他方法实现继承.实现继承的方法很多,下面就只是其中的几种. 一. 原型链继承 function Person() { //被继承的函数叫做超类型(父类,基类) this.name='mumu'; this.age='18'; } Person.prototype.name='susu';//当属性名相同时需就近原则,先在实

  • JavaScript 继承使用分析

    深入学习javascript继承之前,先了解下面的几个概念: 父类:被继承的类 子类:由继承得来的类 超类:也就是父类 抽象类:一般不用来实例化的类,它的用途是用来给其他类继承. 基类:提供给其他类可以继承的类 派生类:由基类继承而来的类 javascript对象继承通常有下面的5种方式: 1.对象冒充 2.call()方式 3.apply()方式 4.原型链 5.混合方式 A.对象冒充 所谓对象冒充,就是新的类冒充旧的类(旧的类必须采用构造函数方式),从而达到继承目的. eg.1 复制代码 代

  • Javascript继承机制的设计思想分享

    我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承. 我花了很多时间,学习这个部分,还做了很多笔记.但是都属于强行记忆,无法从根本上理解. 直到昨天,我读到法国程序员Vjeux的解释,才恍然大悟,完全明白了Javascript为什么这样

  • 深入浅析javascript继承体系

    最近做web项目,接触了jquery等框架,虽然使用方便,但是还是想学习下Javascript,今天分享下最近对js原型继承的理解,不足之处欢迎指正. 一.构造器的原型属性与原型对象 刚接触js时通常依样画瓢,用函数new一个实例,也不知道其原因,只听说js中函数即对象.原来js中没有采用Java等语言中的类继承体系,而是使用原型对象(prototype)实现继承体系,具体说是利用"构造器"实现类的功能. 首先解释下原型继承中的两个重要概念:原型属性.原型对象(实例). 就js对象系统

  • javascript继承机制实例详解

    本文实例讲述了javascript继承机制.分享给大家供大家参考.具体分析如下: 初学javascript一般很难理解Javascript语言的继承机制它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain)模式,来实现继承. 我花了很多时间,学习这个部分,还做了很多笔记.但是都属于强行记忆,无法从根本上理解

  • 浅析2种JavaScript继承方式

    js继承方法最主要的是2种,一种是通过原型的方式,一种是通过借用call&apply的构造函数方式. 1.原型(prototype): function Body(name,age){// 创建一个Body类 this.name = name;// 赋予基础属性name.age this.age = age; } Body.prototype.sayName =function() {// 给原型定义一个sayName的方法 console.log(this.name); } var a = n

  • 使用Promise解决多层异步调用的简单学习心得

    前言 第一次接触到Promise这个东西,是2012年微软发布Windows8操作系统后抱着作死好奇的心态研究用html5写Metro应用的时候.当时配合html5提供的WinJS库里面的异步接口全都是Promise形式,这对那时候刚刚毕业一点javascript基础都没有的我而言简直就是天书.我当时想的是,微软又在脑洞大开的瞎捣鼓了. 结果没想到,到了2015年,Promise居然写进ES6标准里面了.而且一项调查显示,js程序员们用这玩意用的还挺high. 讽刺的是,作为早在2012年就在M

  • JavaScript 继承详解及示例代码

    有些知识当时实在看不懂的话,可以先暂且放下,留在以后再看也许就能看懂了. 几个月前,抱着<JavaScript 高级程序设计(第三版)>,啃完创建对象,就开始啃起了 继承 ,然而啃完 原型链 就实在是看不下去了,脑子越来越乱,然后就把它扔一边了,继续看后面的.现在利用这个暑假搞懂了这个继承,就把笔记整理一下啦. 原型链(Prototype Chaining) 先看一篇文章,文章作者讲的非常不错,并且还配高清套图哦.lol- 链接: [学习笔记] 小角度看JS原型链 从原文中小摘几句 构造函数通

随机推荐