Es6 class

ES6 引入了 Class 语法,作为对象的模板。Class 的构造方法、类的实例化、类的继承、原型属性和 Mixin 模式等方面进行了详细阐述。Class 实质上是函数,其方法不可枚举,且 constructor 是默认的实例化方法。子类继承父类时需使用关键字,super 关键字用于调用父类方法。在类中,prototype 属性是只读的。
摘要由CSDN通过智能技术生成

class

    ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。

class Person{
	constructor(name,age){
		this.name=name;
		this.age=age;
	}
	Fun(){
		return this.x
	}
}

    上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5 的构造函数Point,对应 ES6 的Point类的构造方法。

    Point类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。

    使用的时候,也是直接对类使用 new 命令,跟构造函数的用法完全一致

class end{
	bar(){
		console.log("apple")
	}
}
var i=new end();
i.bar()

   构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Person {
  constructor() {// ... }
 
  toString() {// ...}
 
  toValue() {// ...}
}
 
// 等同于
 
Person.prototype = {
    constructor() {},
    toString() {},
    toValue() {},
};

  rototype对象的constructor属性,直接指向“类”的本身,这与 ES5 的行为是一致的。

Point.prototype.constructor === Point // true

  &enps; 不同的是,类的内部所有定义的方法,都是不可枚举的;而ES5的写法中,函数原型上的方法是可枚举的。

class Point {
  constructor(x, y) {
    // ...
  }

  toString() {
    // ...
  }
}

Object.keys(Point.prototype)
Object.getOwnPropertyNames(Point.prototype)


constructor 方法

   constructor 方法是类的默认方法,创建类的实例化对象时被调用。

class cont{
    constructor(){
      console.log('我是constructor');
    }
}
new cont();

class 定义类

(1)在 class 类上添加的属性都是在原型 prototype 上添加的

(2)new 实例的时候其实就是调用构造函数这个方法

(3)类的本质其实就是一个函数

(4)类中的this 指向实例对象

(5)添加的私有属性都在构造函数中添加

(6)每个构造方法都会默认返回实例对象this,如果人为改变 return 返回值,返回基本数据类型 字符串、数字、布尔等,不会改变return this 的值;如果返回应引用数据类型 对象 数组,那么return this 就会失效,返回你返回的结果

(7)静态方法,在方法名前面加上 static关键字

class Person{
	constructor(x,y){
		this.x = x;
		this.y = y;
	}
	static aa(){
		console.log(123)
	}
}
console.dir(Person)
var as = new Person("pang",18)
Person.as()

类的实例化

new

class 的实例化必须通过 new 关键字。

class cont {}
let emd1 = cont(); 

实例化对象

class cont {
    constructor(x, y) {
        this.x = x;
        this.y = y;
        console.log('cont');
    }
    sum() {
        return this.x + this.y;
    }
}
let emd1 = new cont(2, 1);
let emd2 = new cont(3, 1);
console.log(emd1._proto_ == emd2._proto_);
 
emd1._proto_.sub = function() {
    return this.x - this.y;
}
console.log(emd1.sub());
console.log(emd2.sub()); 

Class 的继承

简介

   Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

class Point {
}

class ColorPoint extends Point {
}

Object.getPrototypeOf()

Object.getPrototypeOf方法可以用来从子类上获取父类。因此,可以使用这个方法判断,一个类是否继承了另一个类

Object.getPrototypeOf(Dog) === Animate   // true

super 关键字

    super 关键字既可以当作函数使用,也可以当作对象使用。

在调用时需要注意两点:

1、子类构造函数中必须调用super方法,否则在新建对象时报错。

2、子类构造函数中必须在使用this前调用super,否则报错。

class Person
  {  
        constructor(x, y) {
          this.x = x;
          this.y = y;
        }
 
        sayName(){
            console.log("the name is:"+this.x);
        }
  }
 
  class Worker extends Person{
    constructor(x, y,job) {
         //报错
    }
    sayJob(){
      console.log("the job is:"+this.job)
    }
  }

    super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

class Animate {
	constructor() {
		this.x = 2
		this.fn = function() {
			console.log('我是父类实例的方法')
		}
	}
	num() {
		console.log('我是父类的num方法')
	}
}
class end extends Animate {
	constructor() {
		super()
	}
	toString() {
    	super.num()   //  调用父类的 num() 方法
    	console.log(super.x)  
        console.log(super.fn) 
        console.log(this.x)
        this.fn()  
	}
}
var end = new end()
end.toString()

类的 prototype 属性和__proto__属性

    prototype是函数特有的属性,是Function的静态属性;__proto__是对象特有的属性。

因为函数本身是一种对象,所以函数既有prototype属性也有__proto__属性。

当函数使用prototype属性时,是作为构造函数使用;

当函数使用__proto__属性时,是作为一个对象使用。

另外,__proto__属性内部属性,尽量不要使用。可以用setPrototypeOf()和getPrototypeOf()代替。

 class C() {}
    console.log(C.prototype);
     console.log(C.__proto__ === Function.prototype);

但是,在class中,prototype属性是只读的

但是,在class中,prototype属性是只读的

class A{}
  class B{
    add(){console.log('add')}
    static add(){console.log('static add')}
  }
  const a = new A();
  const b= new B();
  console.log(Object.getOwnPropertyDescriptor(A, 'prototype'));
  A.__proto__ = B;
  b.add(); 
  A.add();
  A.prototype.__proto__ = B.prototype;
  a.add();

原生构造函数的继承

ES6 允许继承原生构造函数定义子类,因为 ES6 是先新建父类的实例对象this,然后再用子类的构造函数修饰this,使得父类的所有行为都可以继承。下面是一个继承Array的例子。

class MyArray extends Array {
  constructor(...args) {
    super(...args);
  }
}

var arr = new MyArray();
arr[0] = 12;
arr.length

arr.length = 0;
arr[0] 

Mixin 模式的实现

    mixin模式就是一些提供能够被一个或者一组子类简单继承功能的类,意在重用其功能。在面向对象的语言中,我们会通过接口继承的方式来实现功能的复用。

    所谓Mixin模式,就是对象继承的一种替代方案,中文译为“混入”(mix in),意为在一个对象之中混入另外一个对象的方法。

const end = {
	end() { console.log('end') }
};
class MyClass {}
Object.assign(MyClass.prototype, end);
let obj = new MyClass();
obj.end()

    MyMixin是一个混入类生成器,接受superclass作为参数,然后返回一个继承superclass的子类,该子类包含一个end方法。

    接着,目标类再去继承这个混入类,就达到了“混入”end方法的目的。

class MyClass extends MyMixin(MyBaseClass) {
/* ... */
}
let c = new MyClass();
c.end(); 

    如果需要“混入”多个方法,就生成多个混入类。

class MyClass extends Mixin1(Mixin2(MyBaseClass)) {
	/* ... */
}

    这种写法的一个好处,是可以调用super,因此可以避免在“混入”过程中覆盖父类的同名方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值