【ES6】class学习

前言

之前写过一篇剪短的class文章,这次在学习TS的时候,发现对于class的掌握还不是很熟练,于是参考阮一峰老师的《ES6入门》深入学习


写法

如何定义一个类呢?

class Human{
  constructor(name, gender, age){
    this.name = name
    this.gender = gender
    this.age = age
  }
  eat(){
    console.log(`${this.name}饿了,吃饭中···`)
  }
}
  • constructor 方法
    类似于强类型语言的构造方法
    constructor方法是类的默认方法,通过new操作符生成对象实例时,会自动调用该方法。一个类必须有constructor方法,如果在定义类时没有显示定义,会被默认添加一个空的constructor方法。
    constructor方法默认返回实例对象(即this),但也可以指定返回另一个对象。
class Fn{
  constructor (){
    return Object.create(null),
  }
}

new Fn() instanceof Fn  //false

类与ES5的构造函数主要区别是:
类必须使用new操作符来调用,而ES5的构造函数不用new也会执行。


类的实例

ES5一样,实例的属性除非显示定义在本身上,否则都是定义在原型上。
类的所有实例都共享一个原型对象

class Fn{
  constructor(x, y){
    this.x = x
    this.y = y
    this.fn = () => {console.log(`这是实例上的方法`)}
  }
  fn(){
    console.log(`这是原型上的方法`)
   }
}

const a = new Fn(1, 2)
a.fn()  //这是实例上的方法
a.__proto__.fn()  //这是原型上的方法

const b = new Fn('a', 'b')
a.__proto__ === b.__proto__  //true

注意点

  • 严格模式
    类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。只要你的代码写在类或模块中,就只有严格模式可用。

  • 不存在变量提升
    类不存在变量提升,这与ES5完全不同

new Fn()  //error
class Fn(){}
  • name属性
    本质上,ES6的类只是ES5的构造函数的一层包装,所以函数的许多特性都被class继承,包括name属性。

  • this的指向
    类的方法内部如果含有this,它默认指向类的实例。但如果单独使用该方法,很可能报错,因为当你调用一个函数时,this的指向由调用者决定。


静态方法

类相当于实例的原型,所有定义在类中的方法,都会被实例继承,如果在一个方法前加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就是“静态方法”,并且静态方法还可以和非静态方法重名。
如果静态方法内部包含this关键字,这个this指向的是类,不是实例。

class Fn{
  constructor(){}
  static classMethod(){
   this.bar()   
  }
  static bar(){
    console.log('我是类方法')
  }
  bar(){
    console.log('我是原型上的方法')
  }
}

Fn.classMethod()  //我是类方法

父类的静态方法可以被子类继承


实例属性的新写法

实例属性除了定义在constructor()方法里面的this上面,也可以定义在类的最顶层。

class Human{
  name
  age
  gender
  constructor(){}
}

const a = new Human()
a.name  //undefined
a.age  //undefined

静态属性

静态属性是类本身的属性,不是定义在实例对象上的属性,目前最新版的Chrome浏览器已经支持类的静态属性了。

class Fn{
  static prop = 'Hello World'
  constructor(){}
}

Fn.prop  //Hello World

new.target属性

new是从构造函数生成实例对象的命令,ES6为new命令引入了一个new.target属性,一般用于构造函数中,返回new操作符作用对象的构造函数,如果构造函数不是通过nwe调用的,那么new.target会返回 undefined,所以这个属性可以确定构造函数是否通过new调用。

function fn(value){
  if(new.target !== undefined){
    this.value= value
  }else{
    throw new Error('必须使用new操作符生成实例对象')
  }
}

const a = new fn(666)  //正确
const b = fn(666)  //error

在Class内部调用new.target,返回当前Class,子类继承父类是,new.target返回子类。


Class的继承

Class可以通过extends关键字实现继承,相对于ES5通过修改原型链实现继承更加清晰和方便。

class Human{
  constructor(name, age, gender){
    this.name = name
    this.age = age
    this.gender = gender
  }
  eat(){
    console.log('吃饭中···')
  }
}

class Man extends Human{
  constructor(name, age, stature){
    super(name, age)
    this.stature = stature
    this.gender = 'man'
  }
}

const zink = new Man('zink', 21, 174)
zink.eat()  //吃饭中···

ES5的继承是先创造子类对象this,然后将父类的方法绑定到this上(Parent.apply(this))。ES6的机制跟ES5完全不同,先将父类实例对象的属性和方法添加到this上,再用子类的构造哈数修改this

注意点:

  • 子类必须在构造方法里调用super方法,且必须在调用super方法之后在修改this的属性,否则会报错。

super关键字

super这个关键字,既可以当做函数使用,也可以当做对象使用。但是用法不同。

  • 作为函数调用
    super作为函数调用时,只能在子类的constructor方法里调用,代表父类的构造函数。super虽然代表了父类的构造函数,但是返回的是子类的实例,也就是说super内部的this指向子类的实例,所以super()相当于是父类.prototype.constructor.call(this)

  • 作为对象调用
    普通方法中,super表示父类的原型对象,此时只能访问父类原型实例上的属性,并且通过super访问的方法内部的this指向子类实例。
    静态方法中super表示指向父类,此时只能访问父类的静态属性和方法(即用static关键字标注的属性和方法),此时方法内部的this指向子类而不是子类实例

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,731评论 2 9
  • class的基本用法 概述 JavaScript语言的传统方法是通过构造函数,定义并生成新对象。下面是一个例子: ...
    呼呼哥阅读 4,070评论 3 11
  • 简介 Class可以通过extends关键字实现继承。 上面代码定义了一个ColorPoint类,该类通过exte...
    oWSQo阅读 663评论 0 1
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 5,096评论 0 21
  • 九华山,古称陵阳山、九子山,为“中国佛教四大名山”之一,素有“东南第一山”之称,传说因唐朝李白《望九华赠青阳韦仲堪...
    Q喜悦_Liu阅读 430评论 0 0