笔记2--类与继承

82 阅读2分钟

笔记2—类与继承

Created: August 1, 2022 4:15 PM

课程目标

  1. 什么是原型链
  2. 什么是组合寄生式继承,什么是class继承
  3. 如何创建类 function / class

创建对象的方法

  1. Object.create()
const foo = Object.create({});
const bar = {};
​
// foo.__proto__ === {};
// {}.__proto__ === Object.prototype;
foo.__proto__.__proto__ === Object.prototype;
bar.__proto__ === Object.prototype;
let p = Object.create(q);
p.proto === q;

p的原型指向q,需要调用p对象的属性或方法时,若p没有,则在q上查找

  1. var bar = {}
  2. new 关键字
function Person(name){
  this.name = name;
}
​
Person.prototype.getName = function(){
  console.log(this.name);
}
​
const p = new Person('kyle');
​
// 1. new 创建一个对象,指向构造函数的原型
p.__proto__ === Person.prototype;
​
// 2. 构造函数中,有个原型,原型中有个constructor函数,就是构造函数本身
Person.prototype.constructor === Person;
​
// 3. p对象的构造函数,是Person
p.constructor = Person;

new 关键字做了什么

  1. 创建了一个对象

  2. 对象的原型,指向Function的prototype

  3. 对象实现了这个构造函数的方法

  4. 根据一些特定情况,返回对象

    1. 若没有返回值,返回创建的对象
    2. 若有返回值,且是一个对象,则返回对象
    3. 若有返回值,但不是一个对象,则返回创建对象

继承

  • 使用父类的构造函数和原型函数
  • 让对象的原型链指向父类

ES5 原型继承 - 构造函数继承 - 组合继承 - 组合寄生式继承

ES6 class继承

原型继承

function Parent(name){
  this.name = name;
}
​
Parent.prototype.getName = function(){
  console.log(this.name);
}
​
function Child(){};
​
Child.prototype = new Parent();
Child.prototype.constructor = Child;
​
// 隐含问题
// 1. 如果有属性是引用属性,一旦某个实例修改了这个属性,所有都会被修改
// 2. 创建Child时,不可以传参数

构造函数继承

function Parent(actions, name){
  this.actions = actions;
  this.name = name;
}
​
function Child(id){
  Parent.apply(this, Array.prototype.slice.call(arguments, 1));
  this.id = id;
}
​
// 隐含的问题
// 1. 属性或方法,想继承的话,只能在构造函数中定义
// 2。 若方法在构造函数中定义了,每次都会创建(可能造成重复)

组合继承

function Parent(actions, name){
  this.actions = actions;
  this.name = name;
}
Parent.prototype.getName = function(){
  console.log(this.name);
}
​
function Child(id){
  Parent.apply(this, Array.prototype.slice.call(arguments, 1));
  this.id = id;
}
​
Child.prototype = new Parent();
Child.prototype.constructor = Child;

组合寄生式继承

function Parent (actions, name) {
    this.actions = actions;
    this.name = name
}
Parent.prototype.getName = function() {
    console.log(this.name);
}
​
function Child(id) {
    Parent.apply(this, Array.prototype.slice.call(arguments, 1));
    this.id = id;
}
// Child.prototype = Object.create(Parent.prototype);
Child.prototype = inherit(Parent.prototype);
Child.prototype.constructor = Child;
​
///////// class 继承中做的,而狭义上的组合寄生式继承,没有做的。 /////////
for(var k in Parent) {
    if(Parent.hasOwnProperty(k) && !(k in child)) {
        Child[k] = Parent[k];
    }
}
​
function inherit(p) {
    if(p == null) throw TypeError();
    if(Object.create) {
        return Object.create(p);
    }
​
    var t = typeof p;
    if(t !== 'object' && t !=='function') throw TypeError();
    function f() {};
    f.prototype = p;
    return new f();
}

常见问题

A.:组合寄生式继承和class继承有何区别

Q:

  1. class继承,会继承静态属性
  2. 子类中,必须在constructor调用super。因为子类自身的htis对象,必须先通过父类的构造函数完成