• 机构投资者应合理审慎报价 2019-07-16
  • “2018上影之夜”姜文等为“谢晋经典电影回顾展”揭幕 2019-07-10
  • 交大钱学森学院举行毕业典礼 14毕业生赴世界排名前百大学读研 2019-07-10
  • 西安市:构建“五方联动”社会治理新格局 2019-06-23
  • IP定向--云南频道--人民网 2019-06-23
  • 育儿十大坎 新手妈妈快快get起来 2019-06-21
  • 吉林:让更多农村孩子参加少年宫活动 2019-06-21
  • 美国发起贸易战,我们要让世界知道美元、美债并不可靠 2019-06-05
  • 紫光阁中共中央国家机关工作委员会 2019-05-31
  • 监察体制改革后 湘西半年72名公职人员主动交代问题 2019-05-12
  • 媒体宣传报道重庆日报 王国平:扮靓重庆两江四岸” 让城市有机更新 2019-04-26
  • 我相信“交警雨中护送高考生”是真,“交警雨中护送高考生”反被该高考生家长投诉是假。 2019-04-16
  • 14名消防员日巡逻28公里 洗冷水澡 2019-04-10
  • 靶壕有了“蓝军”,百发百中的“神枪手”练起来 2019-04-10
  • 不是秀强大了,别人就会来做朋友,这逻辑不对 2019-04-01
  • 频道栏目
    神奇公式秒杀全国11选5 > 程序开发 > web前端 > HTML/CSS > 正文
    ES6专题—class与面向对象编程-体验javascript之美-SegmentFault思否
    2019-05-11 22:05:10           
    收藏   我要投稿

    在ES5中,我们经常使用方法或者对象去模拟类的使用,并基于原型实现继承,虽然可以实现功能,但是代码并不优雅,很多人还是倾向于用 class 来组织代码,很多类库、框架创造了自己的 API 来实现 class 的功能。

    ES6 时代终于有了 class (类)语法,能让我们可以用更简明的语法实现继承,也使代码的可读性变得更高,同时为以后的JavaScript语言版本添加更多的面向对象特征打下基础。有了ES6的class 以后妈妈再也不用担心我们的代码乱七八糟了,这简直是喜大普奔的事情。ok,我们看看神奇的class.

    一、 类的定义

    1.1 ES5 模拟类定义

    function Person( name , age ) {
        this.name = name;
        this.age = age;
    }
    Person.prototype.say = function(){
        return '我叫' + this.name + ',今年' + this.age + '岁';
    }
    var  p = new Person('大彬哥',18);  // Person?{name: "大彬哥", age: 18}
    p.say()                           //"我叫大彬哥,今年18岁"
    

    使用ES5语法定义了一个Person类,该类有name和age两个属性和一个原型say方法。

    这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大。接下来我们看下ES6 类的写法,这个就很接近于传统面向对象语言了。如果你想了解传统面向对象语言,这里是一个好切入点。

    1.2 ES6 class类定义

    class Person {
      constructor( name , age ) {
        this.name = name;
        this.age = age;
      }
      say() {
        return '我叫' + this.name + ',今年' + this.age + '岁';
      }
    }
    var  p = new Person('大彬哥',18);  // Person?{name: "大彬哥", age: 18}
    p.say()                           //"我叫大彬哥,今年18岁"
    

    上面代码定义了一个同样的Person类,constructor方法就是构造方法,而this关键字则代表实例对象,这更接近传统语言的写法。

    注意:

    虽然引入了class关键字,但ES6中并没有真的引入类这个概念,通过class定义的仍然是函数:

    console.log(typeof Person); // 'function'
    

    所以说,class仅仅是通过更简单直观的语法去实现原型链继承。这种对语言功能没有影响、但是给程序员带来方便的新语法,被称为语法糖。

    图片描述
    二、类的传参 constructor

    在类的参数传递中我们用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。

    class Person {
       constructor(a,b){
            this.a=a;
            this.b=b;
       }
       add(){
            return this.a + this.b;
       }
    }
    let p = new Person(18,30);
    console.log(p.add());  // 48 (18+30)
    

    我们用constructor来传递参数,然后用了一个add方法,把参数相加。这和以前我们的函数传参方法有些不一样,所以小伙伴们要注意转换下思维。

    三、静态方法

    在面向对象语言中,静态方法是指不需要实例化,可以通过类名直接调用的方法,但静态方法不会继承到类实例中,因此静态方法经常用来作为工具函数。比如我们经常用的Math.random(),我们并不需要先new 一个Math然后再去用,一是如果作者那么设计JS一来是没必要,二是用起来太繁琐。

    在使用函数模拟类时,可以像下面这样定义静态方法:

    function Person(name, sex) {}
    
    Person.walk = function() {
        console.log('我会走路')
    }
    
    Person.walk();  // 我会走路
    var person = new Person();
    person.walk();  // TypeError
    

    在ES6 class类定义中,可以使用static关键字定义:

    class Person {
      constructor() {}
    
      static walk(){
          console.log('我会走路')
      }
    }
    Person.walk();  // 我会走路
    var person = new Person();
    person.walk();  // TypeError
    

    static关键字是ES6的另一个语法糖,static 使静态方法声明也成为了一个一等公民。

    于此同时,静态方法也是可以从子类中的super对象上调用的。

    class Person {
      constructor() {}
    
      static walk(){
          return '我会走路'
      }
    }
    
    class People extends Person {
      static walk() {
        return super.walk() + ', 我还会跑步';
      }
    }
    
    People.walk();  //"我会走路, 我还会跑步"
    

    四、封装与继承

    封装和继承,是面向对象编程三大核心特征中非常重要的两个,封装和继承在我们实际生活中也有非常多的应用。举个例子,你去驴肉火烧店去吃饭。

    老板把驴肉面和火烧一起买,起名字叫“精英驴火套餐”,这就是封装。

    而进去以后跟老板说,老板给我来个“82年的驴火套餐”这就是继承。当然了你不仅仅能继承,还能扩展自己的功能。比如你可以跟老板说,老板再给我加一个驴板肠。说的我都饿了,不过我们还是教编程的专栏,不是开店的专栏,我们继续,看看ES6里面怎么玩继承。

    4.1 extends

    旧的原型继承有时看起来让人非常头疼。

    function Child(firstName, lastName, age) {
      Parent.call(this, firstName, lastName)
      this.age = age
    }
    
    Child.prototype = Object.create(Parent.prototype)
    Child.constructor = Child
    

    ES6中新的extends关键字解决了这个问题:

    class Child extends Parent {}
    

    上面代码定义了一个Child类,该类通过extends关键字,继承了Parent类的所有属性和方法。

    由于没有在Child内部写任何代码,所以这两个类完全一样,等于复制了一个Parent类。

    之后,我们在Child内部加上代码:

    class Child extends Parent {
      constructor(firstName, lastName, age) {
        super(firstName, lastName)  
        // 调用父类的constructor(firstName, lastName)
        this.age = age
      }
      speak(){
        return this.age + ' ' + super.speak(); 
        // 调用父类的speak()
      }
    }
    

    使用简介的 extends 达到继承的目的,而非杂乱的 Object.create()、.proto、Object.setPrototypeOf(),这样能让我们更顺利的扩充功能。
    图片描述

    4.2 super

    super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

    (1)super作为函数调用

    代表父类的构造函数,ES6中规定,子类的构造函数必须执行一次super函数。

    class A {}
    
    class B extends A {
      constructor() {
        super();
      }
    }
    

    上面代码中,子类B的构造函数之中的super(),代表调用父类的构造函数,这是必须的,否则 JavaScript 引擎会报错。

    注意,super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。

    (2)super作为对象时,指向父类的原型对象。

    class A {
      p() {
        return 2;
      }
    }
    
    class B extends A {
      constructor() {
        super();
        console.log(super.p()); // 2
      }
    }
    
    let b = new B();
    

    与Java一样,JavaScript也使用extends关键字实现继承,子类中可以通过super关键字调用父类:

    在 constructor 里面,super 的用法是 super()。它相当于一个函数,调用它等于调用父类的 constructor 。

    但在普通方法里面,super 的用法是 super.prop 或者 super.method(),它相当于一个指向对象的 [[Prototype]] 的属性。

    4.3 getter(取值函数)、 setter(存值函数)

    与 ES5 一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

    class Person {
      constructor() {}
      get prop() {
        return 'getter';
      }
      set prop(value) {
        console.log('setter: '+value);
      }
    }
    
    let p = new Person();
    p.prop = 666;   // setter: 666
    p.prop           // 'getter'
    
    

    五、总结

    图片描述

    无论学什么知识,最重要也是最基础的,要实现思想上的转变,目前大部分框架和库,都采用了面向对象方式编程。而且在工作中,要书写中型和大型的项目也经常使用面向对象方式编程,可能大家习惯了面向过程方式编程,其实面向对象方式编程一旦习惯了,会让我开发和思路更宽阔和易于开发项目。

    从学习javascript基础开始的时候,我们就了解了js中的保留字,js中并没有用到,但是将来可能会用到的未来关键字。这些保留字中就包括:class、extends、super。这些就是为将来在js中支持面向对象的类机制而预留的。

    果不其然,现在ES6语法中使用到了这些保留字,这些保留字成功升级成了关键字,可见当时javascript的设计者还是很有前瞻眼光的。

    通过这些新的关键字,使类成为了JS中一个新的一等公民。但是目前为止,这些关于类的新关键字仅仅是建立在旧的原型系统上的语法糖。这样做的原因是为了保证向后兼容性。也就是,旧代码可以在不做任何hack的情况下,与新代码同时运行。

    不过,它使代码的可读性变得更高,并且为今后版本里更多面向对象的新特性打下了基础。

    点击复制链接 与好友分享!回本站首页
    相关TAG标签
    上一篇:Vue项目打包后动态获取自定义变量-前端技术-SegmentFault思否
    下一篇:[打包优化]从0到1搭建element后台框架优化篇-前端小东西-SegmentFault思否
    相关文章
    图文推荐
    点击排行

    关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 神奇公式秒杀全国11选5

    版权所有: 神奇公式秒杀全国11选5--致力于做实用的IT技术学习网站

  • 机构投资者应合理审慎报价 2019-07-16
  • “2018上影之夜”姜文等为“谢晋经典电影回顾展”揭幕 2019-07-10
  • 交大钱学森学院举行毕业典礼 14毕业生赴世界排名前百大学读研 2019-07-10
  • 西安市:构建“五方联动”社会治理新格局 2019-06-23
  • IP定向--云南频道--人民网 2019-06-23
  • 育儿十大坎 新手妈妈快快get起来 2019-06-21
  • 吉林:让更多农村孩子参加少年宫活动 2019-06-21
  • 美国发起贸易战,我们要让世界知道美元、美债并不可靠 2019-06-05
  • 紫光阁中共中央国家机关工作委员会 2019-05-31
  • 监察体制改革后 湘西半年72名公职人员主动交代问题 2019-05-12
  • 媒体宣传报道重庆日报 王国平:扮靓重庆两江四岸” 让城市有机更新 2019-04-26
  • 我相信“交警雨中护送高考生”是真,“交警雨中护送高考生”反被该高考生家长投诉是假。 2019-04-16
  • 14名消防员日巡逻28公里 洗冷水澡 2019-04-10
  • 靶壕有了“蓝军”,百发百中的“神枪手”练起来 2019-04-10
  • 不是秀强大了,别人就会来做朋友,这逻辑不对 2019-04-01
  • 期尾中平特 中超积分榜2019赛程 极速快3吧 羽毛球论坛 三四连码奖上数 山西11选5任2 3d投注技巧及试机号口诀 白小姐玄机图23期 体彩超级大乐透玩法 江苏十一选五中奖计算 竞彩足球比分赛果 海南体彩4十1开奖时间 上海基诺彩票在哪买 32张骨牌牌九图片 分分pk10技巧