笔记 - 面向对象、原型、继承

面向对象

1、对象是什么?

  • 对象是对于单个物体的简单抽象
  • 对象是一个容器,封装了属性 & 方法
  • 属性:对象的状态
  • 方法:对象的行为

2、为什么要面向对象?

  • 逻辑迁徙更加灵活、代码复用性高、高度的模块化
	// 简单对象
	const Course = {
		teacher: '希拉',
		leader: '拉西',
		startCourse: function(name) {
			return `开始${name}`;
		}
	}

	// 函数类
	function Course() {
		this.teacher: '希拉';
		this.leader: '拉西';
		this.startCourse = function(name) {
			return `开始${name}`;
		}
	}

构造函数 - 生成对象

原理

  1. 需要一个模板 - 表征了一类物体的共同特征,从而生成对象
  2. 类即对象模板
  3. js其实本质上并不是基于类,而是基于构造函数 + 原型链
  4. constructor + prototype
    function Course(teacher) {
        this.teacher = teacher;
        this.leader = '小可';
        this.startCourse = function(name) {
            return `开始${name}`;
        }
    }
    const course = new Course('云隐');
  1. Course 本质就是构造函数
  • 函数体内使用的this,指向所要生成的实例
  • 生成对象用new来进行实例化
  • 可以做初始化传参

new 操作符

思考:new是什么 / new的原理 / new时候做了些什么?

    function Course() {};
    const course = new Course();
  • 创建了一个空对象,作为返回的对象实例
  • 将生成空对象的原型对象指向了构造函数的prototype属性
  • 将构造函数内部this指向当前实例对象
  • 执行构造函数的初始化代码

模拟 new 操作符

function _new(fn, ...args) {
  const obj = Object.create(fn.prototype);
  const res = fn.call(obj, ...args);
  return typeof res === 'object' ? res : obj;
}

constructor

原理

    function Course(teacher, leader) {
        this.teacher = teacher;
        this.leader = leader;
    }
    const course = new Course('云隐', '小可');
  • 每个对象在创建时,会自动拥有一个构造函数属性constructor
  • constructor继承自原型对象,指向了构造函数的引用

只使用构造函数 会有什么问题?

    function Course(name) {
        this.teacher = '云隐';
        this.leader = '小可';
        this.startCourse = function(name) {
            return `开始${name}`;
        }
    }

    const course1 = new Course('es6');
    const course2 = new Course('OOP');
    // 构造函数中的方法,会存在于每一个生成的实例里,重复的挂载其实是会导致资源浪费
    // 解决办法:使用原型链

原型对象

    function Course() {};
    const course1 = new Course();
    const course2 = new Course();
  1. 构造函数: 用来初始化创建对象的函数 - Course
    **自动给构造函数赋予一个属性prototype,该属性等于实例对象的原型对象
  2. 实例对象:course1是实例对象,根据原型对象创建出来的实例
    **每个对象中都有一个__proto__
    **每个实例对象都有一个constructor
    **constructor由继承而来,并指向当前的构造函数
  3. 原型对象:Course.prototype
	function Course() {};
    Course.prototype.teacher = '云隐';
    const course1 = new Course();
    const course2 = new Course();

    // 对上篇原型对象做优化
    function Course() {
        this.teacher = '云隐';
        this.leader = '小可';
    }
    
    // 方法挂载于prototype上
    Course.prototype.startCourse = function(name) {
        return `开始${name}`;
    }

    const course1 = new Course('es6');
    const course2 = new Course('OOP');

继承

原型链继承

	function Game() {
		this.name = 'lol';
	}

	Game.prototype.getName = function() {
		return this.name;
	}

	function LOL() {}
	LOL.prototype = new Game();
	LOL.prototype.constructor = LOL;
	
  1. 优点
    **在原型对象上的属性和方法,能被所有实例共享
  2. 缺点
    function Game() {
        this.name = 'lol';
        this.skin = ['s'];
    }
    Game.prototype.getName = function() {
        return this.name;
    }

    // LOL类
    function LOL() {}
    LOL.prototype = new Game();
    LOL.prototype.constructor = LOL;
    const game1 = new LOL();
    const game2 = new LOL();
    game1.skin.push('ss');

**原型对象的属性因为共享,一个实例改变会影响所有实例
**实例化子类实例时,无法向父类传参

构造函数继承

	function Game(arg) {
		this.name = arg.name;
		this.skin = arg.skin;
	}

	Game.prototype.getName = function() {
		return this.name;
	}

	function LOL(arg) {
		Game.call(this, arg);
	}

	let lol = new LOL({name: 'lol', skin: ['s']});
	// 解决了无法向父类传参和子类原型属性共享的问题
  1. 优点
    **解决了无法向父类传参和子类原型属性共享的问题
  2. 缺点
    **无法使用父类原型对象上的方法

组合式继承

	function Game(arg) {
		this.name = arg.name;
		this.skin = arg.skin;
	}

	Game.prototype.getName = function() {
		return this.name;
	}

	function LOL(arg) {
		Game.call(this, arg);
	}

	LOL.prototype = new Game();
	LOL.prototype.constructor = LOL;
  1. 优点:解决了构造函数继承和原型链继承的问题
  2. 缺点:父类构造函数调用了2次

寄生组合式继承

	function Game(arg) {
		this.name = arg.name;
		this.skin = arg.skin;
	}

	Game.prototype.getName = function() {
		return this.name;
	}

	function LOL(arg) {
		Game.call(this, arg);
	}

	LOL.prototype = Object.create(Game.prototype);
	LOL.prototype.constructor = LOL;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值