原型&原型链

115 阅读2分钟

单例模式

全局有且仅有一个实例对象(比如vue/react全局路由对象)

new做了什么操作

  1. 结构上:创建一个空对象,作为返回的对象实例
  2. 属性上:将生成空对象的原型对象属性指向了构造函数的prototype属性
  3. 关系上:将当前实例对象赋值给了内部的this
  4. 生命周期上:执行了构造函数的初始化代码
手写实现一个new
function userNew(obj, ...args) {
    const newObj = Object.create(obj.prototype);
    const result = obj.apply(newObj, args);
    return typeof result === 'object' ? result : newObj;
}

constructor是什么

  1. 每个对象在创建时,会自动拥有一个构造函数constructor属性
  2. constructor源自原型对象,指向了构造函数的引用

原型对象

function Course() {};
const course1 = new Course();
const course2 = new Course();

* 1. course1.__proto__ = Course.prototype;
* 2. course1.constructor = Course;

js如何实现继承

原型链继承
// 在原型对象的所有属性和方法,都可以被实例所继承
* 1. 属性挂载在模板(类)上,方法挂载在原型上
function Game() {
    this.name = 'lol';
}
Game.propotype.getName = function() {
    return this.name;
}
// LOL
function LOL() {};
LOL.prototype = new Game();
LOL.prototype.constructor = LOL;
const game = new LOL();
// 本质:重写了原型对象方式,将父对象的属性方法,作为自对象原型的属性方法,同时重写构造函数
// 原型链直接继承有什么缺陷吗
* 1. 父类存在引用类型属性时,被其中一个子类更改后,会影响到所有使用该属性的子类
* 2. 子类无法向父类进行传参
// 如何解决--构造函数继承
构造函数继承
function Game(args) {
    this.name = 'lol';
}
Game.propotype.getName = function() {
    return this.name;
}
// LOL
function LOL(args) {
    Game.call(this, args)
};
const game3 = new LOL('args');
// 解决了共享属性+子向父传参问题
// 存在问题 原型链上的方法无法被继承 如何解决--组合继承
组合继承
function Game(args) {
    this.name = 'lol';
}
Game.propotype.getName = function() {
    return this.name;
}
// LOL
function LOL(args) {
    Game.apply(this, args)
};
LOL.proptotype = new Game();
LOL.proptotype.constructor = LOL;
const game4 = new LOL('args');
// 组合继承就没有问题了吗? 问题在于无论何种场景,都会调用两次父类构造函数
// 解决办法 寄生组合式继承
寄生组合式继承
function Game(args) {
    this.name = 'lol';
}
Game.propotype.getName = function() {
    return this.name;
}
// LOL
function LOL(args) {
    Game.apply(this, args)
};
LOL.proptotype = Object.create(Game.prototype);
LOL.proptotype.constructor = LOL;
const game5 = new LOL('args');
如何实现多重继承
function Game(args) {
    this.name = 'lol';
}
Game.propotype.getName = function() {
    return this.name;
}
function Store() {
    this.shop = 'steam';
}
function LOL(args) {
    Game.call(this, args);
    Store.call(this, args);
};
LOL.proptotype = Object.create(Game.prototype);
Object.assin({
    Store.prototype,
    LOL.prototype
});
LOL.proptotype.constructor = LOL;