笔记2—类与继承
Created: August 1, 2022 4:15 PM
课程目标
- 什么是原型链
- 什么是组合寄生式继承,什么是class继承
- 如何创建类 function / class
创建对象的方法
- 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上查找
- var bar = {}
- 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 关键字做了什么
-
创建了一个对象
-
对象的原型,指向Function的prototype
-
对象实现了这个构造函数的方法
-
根据一些特定情况,返回对象
- 若没有返回值,返回创建的对象
- 若有返回值,且是一个对象,则返回对象
- 若有返回值,但不是一个对象,则返回创建对象
继承
- 使用父类的构造函数和原型函数
- 让对象的原型链指向父类
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:
- class继承,会继承静态属性
- 子类中,必须在constructor调用super。因为子类自身的htis对象,必须先通过父类的构造函数完成