js(原型&class类)

146 阅读2分钟

原型&原型链

原型
prototype
作用
共享属性和方法

prototype
构造函数通过原型(prototype)构造的属性方法是所有对象共有的
每一个构造函数都有一个 prototype 属性,指向另一个对象,注意这个 prototype 就是一个对象
这个对象的所有属性和方法都会被构造函数拥有

1.原型是什么
一个对象,我们也称 prototype 为原型对象
2.原型的作用是什么
共享属性和方法

原型链
__proto__
作用
继承的本质是原型链
对象都有一个方法 __proto__, 指向构造函数的原型对象的 prototype ,之所以我们对象可以使用构造函数
prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在

constructor 
指向构造函数本身

Star.prototype = {
  sum:function(){},
  cat:function(){},
  constructor:Star //如果我们修改了原来的原型对象,如给原型对象赋值一个对象,需要手动设 constructor
}
function Star(){}
var that;
Star.prototype.add = function(){
  that = this; // 在构造函数里面的this指向的是实例对象
}
var test = new Star();
test.add();
console.log(that === test)//true 

原型链的终端 - Object.prototype

test__proto__ === Star.prototype
test.__proto__.constructor === Star.prototype.constructor  //true
Star.prototype.__proto__ === Object.prototype  //true
Object.prototype.__proto__ === null //true

绝对大多数对象继承自Object.prototype
除了使用 Object.create 添加null
Object.create(原型prototype) 
var obj = {name:'bob'}
var obj1 = Object.create(obj) //obj1.__proto__ === obj

class类

  1. extends 继承
  2. super 调用父类的方法
  3. constructor 构造器
  4. 类里面没有变量提升,所以先有类才能实例化对象
class Father{
    say(){
       return '我是爸爸';
    }
}
class Son extends Father{
    say(){
       console.log(super.say()+ '的儿子'); super调用父类方法
    }
}
var test = new Son();


 abstract class Father {
    constructor(x,y){
      this.x = x;
      this.y = y;
    };
    add(){
      return this.x + this.y;
    }
  }
  class Son extends Father{
    constructor(x, y){
      super(x,y);
      this.x = x;
      this.y = y;
    }
    cut(){
      console.log(this.x - this.y);
    }
  }

let test = new Son(10,5);
test.add()//15
test.cut()//5


abstract class Father { 
  // abstract开头就是抽象类 无法创建实例 只能被继承 抽象类可以添加抽象方法
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  say() {
    console.log('我是爸爸的方法');
  }
  //abstract开头就是抽象方法,没有方法体,抽象方法只能定义在抽象类中 子类必须对抽象方法进行重写
  abstract public():void;
}

class Son extends Father {
  color: string
  constructor(name: string, age: number, color: string) {
  //father最大 如果在子类中写了构造函数(constructor)
  则在子类的构造函数中必须调用父类的构造函数 
    super(name, age)//super调用父类的构造函数
    this.color = color;
  }
  say(): void {
    // super.say();
    console.log('我覆盖了爸爸的方法');
    
  }
  public(): void {
      console.log('父类是抽象类定义了抽象方法,就必须在子类中重写');
  }
}

let test = new Son('小明', 18, 'red');