Class and inheritance in ES6 --scallops

Class and inheritance in es6

Foreword:

There are only objects in traditional javascript, and there is no concept of class. It is a prototype-based object-oriented language. The characteristic of the prototype object is to share its own properties with the new object. Compared with other traditional object-oriented languages, this way of writing is unique and unacceptable!

Classes in ES5

In ES5, if you want to generate an object instance, you need to define one first 构造函数, and then use newthe operator to complete it.

Example:
//构造函数名大写(非强制,但这么写有助于区分构造函数和普通函数)
function Person(name,age) {
    
    
    this.name = name;
    this.age=age;
}
Person.prototype.say = function(){
    
    
    return "我的名字叫" + this.name+"今年"+this.age+"岁了";
}
var obj=new Person("tom",88);//通过构造函数创建对象,必须使用new 运算符
console.log(obj.say());//我的名字叫tom今年88岁了
The execution process of the constructor to generate an instance:
c1.当使用了构造函数,并且new 构造函数(),后台会隐式执行new Object()创建对象;
2.将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this就代表new Object()出来的对象。
3.执行构造函数的代码。
4.返回新对象(后台直接返回);

Classes in ES6

ES6 introduced the concept of class (class), which can be defined through the class keyword. The appearance of this keyword
makes javascript clearer in object writing, more like an object-oriented language.

Change the previous code to ES6:
class Person{//定义了一个名字为Person的类
    constructor(name,age){//constructor是一个构造方法,用来接收参数
        this.name = name;//this代表的是实例对象
        this.age=age;
    }
    say(){//这是一个类的方法,注意千万不要加上function
        return "我的名字叫" + this.name+"今年"+this.age+"岁了";
    }
}
var obj=new Person("laotie",88);
console.log(obj.say());//我的名字叫laotie今年88岁了
Note:
1.在类中声明方法的时候,千万不要给该方法加上function关键字
2.方法之间不要用逗号分隔,否则会报错

As can be seen from the following code, a class is essentially a function. The class itself points to the constructor. So it can be considered that the class in ES6 is actually another way of writing the constructor!


console.log(typeof Person);//function
console.log(Person===Person.prototype.constructor);//true

The following code illustrates the properties of constructors prototype, which still exist in ES6 classes.

console.log(Person.prototype);//输出的结果是一个对象

In fact, all methods of a class are defined on the prototype property of the class. The code proof is as follows:

Person.prototype.say=function(){
    
    //定义与类中相同名字的方法。成功实现了覆盖!
    return "我是来证明的,你叫" + this.name+"今年"+this.age+"岁了";
}
var obj=new Person("kity",88);
console.log(obj.say());//我是来证明的,你叫kity今年88岁了

Of course, you can also add methods to the class through the prototype attribute. as follows:

Person.prototype.addFn=function(){
    
    
    return "我是通过prototype新增加的方法,名字叫addFn";
}
var obj=new Person("kity",88);
console.log(obj.addFn());//我是通过prototype新增加的方法,名字叫addFn

You can also dynamically add methods to objects through the object.assign method

Object.assign(Person.prototype,{
    
    
    getName:function(){
    
    
        return this.name;
    },
    getAge:function(){
    
    
        return this.age;
    }
})
var obj=new Person("kity",88);
console.log(obj.getName());//kity
console.log(obj.getAge());//88

The constructor method is the default method of the constructor of the class. When an object instance is generated through the new command, this method is automatically called.

class Box{
    
    
    constructor(){
    
    
        console.log("啦啦啦,今天天气好晴朗");//当实例化对象时该行代码会执行。
    }
}
var obj=new Box();

If the constructor method is not explicitly defined, a constructor method will be implicitly generated. So even if you didn't add the constructor, the constructor exists. The constructor method returns the instance object this by default, but you can also specify that the constructor method returns a brand new object so that the returned instance object is not an instance of the class.

class Desk{
    
    
    constructor(){
    
    
        this.aa="我是一只小小小小鸟!哦";
    }
}
class Box{
    
    
    constructor(){
    
    
       return new Desk();// 这里没有用this哦,直接返回一个全新的对象
    }
}
var obj=new Box();
console.log(obj.aa);//我是一只小小小小鸟!哦

The attributes defined in the constructor can be called strength attributes (that is, defined on the this object), and the attributes that are exogenous to the constructor are defined on the prototype, which can be called prototype attributes (that is, defined on the class). The hasOwnProperty() function is used to determine whether the property is an instance property. The result is a Boolean value, true means it is an instance attribute, false means it is not an instance attribute. The in operator returns true if the given property is accessible through the object, whether the property exists on the instance or on the prototype.

class Box{
    
    
    constructor(num1,num2){
    
    
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
    
    
        return num1+num2;
    }
}
var box=new Box(12,88);
console.log(box.hasOwnProperty("num1"));//true
console.log(box.hasOwnProperty("num2"));//true
console.log(box.hasOwnProperty("sum"));//false
console.log("num1" in box);//true
console.log("num2" in box);//true
console.log("sum" in box);//true
console.log("say" in box);//false

All instances of the class share a prototype object, and their prototypes are Person.prototype, so the proto properties are equal

class Box{
    
    
    constructor(num1,num2){
    
    
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
    
    
        return num1+num2;
    }
}
//box1与box2都是Box的实例。它们的__proto__都指向Box的prototype
var box1=new Box(12,88);
var box2=new Box(40,60);
console.log(box1.__proto__===box2.__proto__);//true

Therefore, it is also possible to add methods to classes through proto. Using the proto attribute of an instance to rewrite the prototype will change the original definition of the Class and affect all instances, so it is not recommended!

class Box{
    
    
    constructor(num1,num2){
    
    
        this.num1 = num1;
        this.num2=num2;
    }
    sum(){
    
    
        return num1+num2;
    }
}
var box1=new Box(12,88);
var box2=new Box(40,60);
box1.__proto__.sub=function(){
    
    
    return this.num2-this.num1;
}
console.log(box1.sub());//76
console.log(box2.sub());//2

Class does not have variable promotion, so it needs to be defined before use. Because ES6 will not promote the definition of the class to the code header, but ES5 is different. ES5 has variable promotion, which can be used first and then defined.

//ES5可以先使用再定义,存在变量提升
new A();
function A(){
    
    

}
//ES6不能先使用再定义,不存在变量提升 会报错
new B();//B is not defined
class B{
    
    

}

Inheritance in ES5 (Composition Inheritance: Prototype Chain Inheritance + Borrowing Inheritance)

Prototype chain inheritance:

The instance of the parent class serves as the prototype of the subclass

function Persion(name,age){
    
    
    this.name=name;
    this.age=age;
    this.say=function(){
    
    
        console.log(`${
     
     this.name} ${
     
     this.age}`);
    }
}
Persion.prototype.test=function(){
    
    
    console.log("我是原型上的方法");
}
//子类
function Women(){
    
    
    this.sex='女'
}
Women.prototype=new Persion('kity',18);//父类的实例作为子类的原型

var one=new Women('tom',20);
one.say();//kity 18  子类实例,不能向父类构造函数中传参数
one.test();// 可以调用原型方法 我是原型上的方
borrow constructor

In the subclass, use call() to call the parent class method, and change the this of the parent class to the this of the subclass, which is equivalent to copying the instance attributes of the parent class and putting it in the function of the subclass

//父类
function Persion(name,age){
    
    
    this.name=name;
    this.age=age;
    this.say=function(){
    
    
        console.log(`${
     
     this.name} ${
     
     this.age}`);
    }
}
Persion.prototype.test=function(){
    
    
    console.log("我是原型上的方法");
}
//子类
function Women(){
    
    
    //在子类内,使用call()调用父类方法,并将父类的this修改为子类的this.相当于是把父类的实例属性复制了一份放到子类的函数内.
    Persion.call(this);
    this.name="child";
    this.age=18;
}
var one=new Women();
one.say();//child 18
one.test();// 报错 不能继承原型上的方法
Composition inheritance

Both the parent class instance attribute and the parent class prototype attribute can be called

//解决方法,组合是继承,把子类的原型变成父类的实例
function Persion(name,age){
    
    
    this.name=name;
    this.age=age;
    this.say=function(){
    
    
        console.log(`${
     
     this.name} ${
     
     this.age}`);
    }
}
Persion.prototype.test=function(){
    
    
    console.log("我是原型上的方法");
}
//子类
function Women(name,age,sex){
    
    
    Persion.call(this,name,age);//实现继承的一种方式
    this.sex=sex
}
Women.prototype=new Persion();//把Women的原型变成Persion的实例(因为Women的实例能够访问到Women原型上的方法)

var c=new Women('tom',20,'女');
c.say();
c.test();//成功继承原型上的方法

class inheritance in ES6

  • parent class (base class)
  • Subclass
  • extendskeywords
//class 相当于es5中构造函数
//class中定义方法时,前后不能加function,全部定义在class的protopyte属性中
//class中定义的所有方法是不可枚举的
//class中只能定义方法,不能定义对象,变量等
//class和方法内默认都是严格模式
//es5中constructor为隐式属性


//父类
class People{
    
    
  constructor(name='wang',age='27'){
    
    
    this.name = name;
    this.age = age;
  }
  eat(){
    
    
    console.log(`${
     
     this.name} ${
     
     this.age} eat food`)
  }
}
//子类 通过extends 继承父类
class Woman extends People{
    
     
   constructor(name = 'ren',age = '27'){
    
     
     //继承父类属性
     super(name, age); 
   } 
    eat(){
    
     
     //继承父类方法
      super.eat() 
    } 
} 
let wonmanObj=new Woman('xiaoxiami'); 
wonmanObj.eat();

Guess you like

Origin blog.csdn.net/weixin_50407990/article/details/110091229