【JavaScript高级】class类、ES6实现继承、ES6对象增强

class类

ES6(ECMAScript2015)新的标准中使用了class关键字来直接定义类。

有两种定义方式:类声明和类表达式。

注意: 类结构中定义多个内容, 不需要加逗号进行分隔

//类声明
class Person{

}

//类表达式
var Student=class{
    
}

构造函数

  • 每个类都可以有一个自己的构造函数(方法),这个方法的名称是固定的constructor
  • 通过new操作符,操作一个类的时候会调用这个类的构造函数constructor
  • 每个类只有一个构造函数,如果包含多个构造函数,那么会抛出异常

当我们通过new关键字操作类的时候,会调用这个constructor函数,并且执行如下操作:

  1. 在内存中创建一个新的空对象
  2. 这个对象内部的prototype属性会被赋值为该类的prototype属性
  3. this指向创建出来的新对象
  4. 执行构造函数的内部代码(函数体代码)
  5. 如果构造函数没有返回非空对象,则默认返回创建出来的新对象

实例的隐式原型会绑定Person的显式原型

class Person {
  // 类中的构造函数
  // 当我们通过new关键字调用一个Person类时, 默认调用class中的constructor
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

var p1 = new Person("coder", 18);

console.log(p1.name, p1.age); // coder 18
// 实例的隐式原型会绑定Person的显式原型
console.log(p1.__proto__ === Person.prototype); // true

注意: function定义的类可以作为普通函数去调用; class定义的类, 不能作为一个普通函数调用

访问器方法:getter和setter

对象的访问器方法:通过属性描述符定义访问器

var obj = {
  // 程序员之间的约定: 以下划线开头的属性和方法, 是不在外界访问的
  _name: "kaisa"
}

Object.defineProperty(obj, "name", {
  set: function(value) {
    this._name = value
  },
  get: function() {
    return this._name
  }
})

class的访问器方法:

class Person {
  constructor(name, age) {
    this.name = name;
    this._age = age;
  }

  set age(value) {
    this._age = value;
  }

  get age() {
    return this._age;
  }
} 

静态方法

ES5的静态方法:在类上添加或调用的方法。

function Person() {}
// 添加实例方法
Person.prototype.running = function() {}

// 添加静态方法(类方法)
Person.eating = function() {}

var p1 = new Person()
p1.running() // 调用实例方法
Person.eating() // 调用静态方法

ES6中class, 使用static关键字来定义静态方法(类方法):

class Person {
  // 实例方法
  eating() {}
  running() {}

  // 类方法
  static studying() {}
}
var p1 = new Person();
p1.running(); // 调用实例方法
p1.eating(); // 调用实例方法

Person.studying(); // 调用类方法

注意: 实例方法的this指向实例对象, 静态方法的this指向类

ES6实现继承

extends

关键字:extends

//父类
class Person{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }

    running(){
        console.log("runninng!");
    }
}

//子类
class Student extends Person{
    constructor(name,age,id){
        //super 调用父类构造函数, 将属性传进去
        super(name,age);
        this.id=id;
    }

    studying(){
        console.log("studying!");
    }
}

//子类实例
var stud1=new Student("a",18,1);
stud1.running()//runninng!
stud1.studying()//studying!

super

  • super.method(…):调用一个父类方法
  • super:调用父类constructor(只能在constructor中使用)

注意:

  • (派生)类的构造函数中使用this或者返回(return)默认对象之前,必须先通过super调用父类的构造函数
  • 使用位置:子类的构造函数、实例方法、静态方法(类方法)

位置一:举例如上

位置二:实例方法

class Person{
    running(){
        console.log("Person running!");
    }
}

class Student extends Person{
    running(){
        //调用父类的running
        super.running();
        //子类的running
        console.log("Studeng running!");
    }
}

var stu1=new Student();
stu1.running();//Person running! Studeng running!

位置三: 静态方法——注意要通过类调用

class Person{
    static running(){
        console.log("static Person running!");
    }
}

class Student extends Person{
    static running(){
        super.running()
        console.log("static Student running!");
    }
}

//要通过类调用
Student.running()//static Person running!  static Student running!

继承内置类

让我们的类继承自内置类,如:

class MyArray extends Array {
    lastItem(){
        return this[this.length-1];
    }
}

var arr = new MyArray(1,2,3,4,5);
console.log(arr.lastItem());//5

也可以直接对Array进行扩展,如:

Array.prototype.lastItem = function() {
  return this[this.length - 1]
}

var arr = new Array(10, 20, 30, 40);
console.log(arr.lastItem()); // 40

类的混入(了解)

JavaScript的类只支持单继承:也就是只能有一个父类。

若我们需要在一个类中添加更多相似的功能时,可以使用混入(mixin)

//传入一个类,返回一个类
//这个类继承自传入的类,并添加running方法
function mixinRun(BaseClass){
    return class extends BaseClass{
        running(){
            console.log("running!");
        }
    }
}

function mixinFly(BaseClass){
    return class extends BaseClass{
        flying(){
            console.log("flying!");
        }
    }
}

class Bird{
    eating(){
        console.log("eating!");
    }
}

//把Bird跟Fly、Run混在一起,得到一个会飞会跑的小鸟
class newBird extends mixinFly(mixinRun(Bird)){}

var bird=new newBird();

bird.flying()//flying!
bird.running()//running!
bird.eating()//eating!

这种写法和react的高阶组件中的写法是非常相似。

ES6对象的增强

字面量的增强

增强对象字面量:Enhanced object literals。主要包括:

  1. 属性的简写
  2. 方法的简写
  3. 计算属性名

1.属性的简写

简写前:

var name = "kaisa";
var age = 18;

// 一般情况写我们会这样写
var obj = {
  name: name,
  age: age
};

简写后:key和value的标识符一样的情况下可以使用

var name = "kaisa";
var age = 18;

// 属性的增强写法
var obj = {
  name,
  age
};

2.方法的简写

简写前:

var obj = {
  running: function () {},
  eating: function () {},
};

简写后:

var obj = {
  running() {},
  eating() {},
};

3.计算属性名

想要使用变量key的值, 作为obj对象的属性名:

var key = "address";

var obj = {
  [key]: "成都市",
};

console.log(obj.address); // 成都市

解构

ES6中新增了一个从数组或对象中方便获取数据的方法,称之为解构Destructuring。分为:

  1. 数组的解构
  2. 对象的解构

1.数组的解构

基本解构:

var names=["a","b","c","d"]

var [n1,n2,n3]=names
console.log(n1,n2,n3);//a b c

顺序解构:严格按顺序,不要的要空出来

var names=["a","b","c","d"]

var [n1,,n3]=names
console.log(n1,n3);//a c

…语法:…里的会放入一个新数组里

var names=["a","b","c","d"]

var [n1,...rest]=names
console.log(n1,rest);//a (3) ['b', 'c', 'd']

默认值:若某个值是undefined,我们可以给它赋值。

var names=["a","b",undefined,"d"]

var [n1,n2,n3="defined"]=names
console.log(n1,n2,n3);//a b defined

2.对象的解构

基本解构:

var obj={
    name:"name",
    age:18,
    height:1.88
}

var {name,height}=obj
console.log(name,height);//name 1.88

任意顺序:

var obj={
    name:"name",
    age:18,
    height:1.88
}

var {height,name}=obj
console.log(height,name);//1.88 'name'

重命名:对变量进行重命名

var obj={
   name:"name",
   age:18,
   height:1.88
}

var {name:namee,height:heightt,age:agee}=obj
console.log(namee,heightt,agee);//name 1.88 18

默认值:可以添加key并对其设置默认值

var obj={
    name:"name",
    age:18,
    height:1.88
}

var {
    name,age,address:Address="add"
}=obj;

console.log(name,age,Address);//name 18 add

…语法:

var obj={
    name:"name",
    age:18,
    height:1.88
}

var {name,...rest}=obj
console.log(rest);//{age: 18, height: 1.88}

解构相关应用

function getPosition({x,y}){
    console.log(x,y);
}

//相当于做了{x,y}={x:10,y:100}这个操作
getPosition({x:10,y:100});

多态

  • 为不同数据类型的实体提供统一的接口,或使用一个单一的符号来表示多个不同的类型
  • 不同的数据类型进行同一个操作,表现出不同的行为

如:

function sum(a,b){
    console.log(a+b);
}

sum(1,2)//3
sum("1","2")//12

参考

coderwhy的课
JavaScript中class类、ES6中实现继承的方法
JavaScript面向对象(3)—深入ES6的class
JavaScript中ES6对象的增强使用、解构、多态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

karshey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值