美文网首页
lesson 5 面向对象及原型链 2021-04-29

lesson 5 面向对象及原型链 2021-04-29

作者: jeff_nz | 来源:发表于2021-05-11 08:20 被阅读0次

课程标题 面向对象及原型链

课程目标

  1. 面向对象思想
  2. 原型及原型链
  3. 继承

知识点

  1. 面向对象思想
  2. 原型链的指向
  3. new关键字的步骤

new关键字做了什么?

  1. 创建一个新的对象,继承自构造函数的原型。
  2. 实例的proto指向构造函数的prototype。
  3. 将this指向新创建的对象。
  4. 返回这个新创建的对象。
    a. 如果构造函数没有显示的返回值或者返回值是基本类型,返回this
    b. 如果构造函数有显示的返回值且是对象类型,返回这个对象
 function Player(name){
   this.name = name;
 }

 function objectFactory(){
    let obj = new Object();
    let FunctionConstructor = [].shift.call(arguments);
    obj.__proto__ =FunctionConstructor.prototype;
    let resultObj = FunctionConstructor.apply(obj,arguments);
    return typeof resultObj === 'object' ? resultObj : obj;
 }

 const p1 = objectFactory(Player,'df');

 console.log(p1);

继承

原型链继承

function Parent(){
  this.name = 'parentName';
}

Parent.prototype.getName = function ()
 {
  console.log(this.name)
}

function Child () {}

// const child = new Child();
// child.__proto__ === Child.prototype
// Child.prototype.__proto__ === Parent.prototype
Child.prototype = new Parent();
Child.prototype.constructor = Child

const child1 = new Child()
child1.getName()

隐含的问题

  1. 如果一个实例操作了引用类型的原型属性,所有实例都会受到影响。
  2. 创建Child实例的时候无法传参

构造函数继承

针对上述问题1, 想办法把Parent上的属性和方法,添加/复制到Child上而不是都存在原型对象/Parent上,防止被实例共享。

实现

function Parent() {
  this.actions=['eat','sleep'];
  this.name = 'parentName';
}

function Child() {
  Parent.call(this)
  // 相当于执行了Parent内部的两个语句
  // this.actions = ['eat', 'sleep'];
  // this.name = 'parentName';
}
const child1 = new Child()
const child2 = new Child()
child1.actions.pop();
console.log(child1.actions)   // ['eat']
console.log(child2.actions)   // ['eat', 'sleep']

解决第二个不能传参的问题

function Parent(name,actions) {
  this.actions=actions;
  this.name = name;
}

function Child(id,name,actions) {
  Parent.call(this,name,actions)
  this.id = id; 
}
const child1 = new Child('c1','c1name',['eat'])
const child2 = new Child('c2','c2name',['play','jump','ball'])
console.log(child1.actions)   // ['eat']
console.log(child2.actions)   // ['play','jump','ball']

隐含的问题

  1. 属性或者方法被继承的话,只能在构造函数中定义。每次创建实例都会执行一遍构造函数,多占用内存。

组合集成

原型链继承,实现了基本的继承,方法存在prototype上,子类可以直接调用,但是引用类型的属性会被所有实例共享,并且不能传参。
构造函数继承,解决了原型链的两个问题,但是构造函数内重复创建方法,导致内存占用过多。

实现

function Parent(name,actions) {
  this.actions=actions;
  this.name = name;
}
Parent.prototype.eat = function (){
  console.log('eat')
}
function Child (id) {
     Parent.apply(this,Array.from(arguments).slice(1));
    this.id = id;
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

const c1 = new Child(1, 'c1',['xxx'])
const c2 = new Child(2, 'c2', ['hhhh'])

c1.eat();
c2.eat();

隐含的问题

  1. 调用了两次Parent的构造函数,做了无意义的重复操作。

寄生组合式继承

为了解决上述问题

function Parent(name,actions) {
  this.actions=actions;
  this.name = name;
}
Parent.prototype.eat = function (){
  console.log('eat')
}
function Child (id) {
    Parent.apply(this,Array.from(arguments).slice(1));
    this.id = id;
}

// Child.prototype = new Parent();
//let TempFunction = function () {};
//TempFunction.prototype = Parent.prototype;
//Child.prototype = new TempFunction();
Child.prototyp = Object.create(Parent.prototyp);

Child.prototype.constructor = Child;
const c1 = new Child(1, 'c1',['xxx'])
const c2 = new Child(2, 'c2', ['hhhh'])

c1.eat();
c2.eat();

class

class Parent {
    constructor(){
      this.name ='aaa';
    }
  getName() {
    console.log('getName');
  }
}

class Child extends Parent {
    constructor() {
      super() ;   
    }
}

const p1 = new Child ();
p1.getName()

课后问题

  1. new 做了什么? 如何实现
    a. 基于构造函数的prototype创建了一个对象。
    b. 将this指向这个对象。
    c. 实例的proto指向构造函数的prototype。
    c. 返回这个新创建的对象,如果构造函数没有返回或者返回了值类型,直接返回this,如果构造函数返回引用类型,返回这个对象。
  2. 4种继承方式的优缺点?如何实现?
    a.原型链
    b. 构造函数
    c. 组合模式
    d. 寄生组合模式 可用Objec.create()模拟
  3. 如何判断一个函数是否用了同一块内存地址?
    用严格相等 ===
  4. 如何在原型链上去找一个属性?

相关文章

  • lesson 5 面向对象及原型链 2021-04-29

    课程标题 面向对象及原型链 课程目标 面向对象思想 原型及原型链 继承 知识点 面向对象思想 原型链的指向 new...

  • 1.web前端基础储备之—js的面向对象风格以及原型和原型链

    javascript是面向对象风格,基于原型的语言。 目标:了解js面向对象和原型原型链的关系 面向对象(OOP)...

  • Js面向对象

    一、Js面向对象 二、Js原型及原型链 1、原型 JavaScript 的每个对象都继承另一个父级对象,父级对象称...

  • JS汇总---面向对象&数组

    面向对象 js原型链的继承 静态属性怎么继承 js原型链以及特点 面向对象有哪几个特点 封装,继承,多态 对象的继...

  • 在nodejs中面向对象:Bearcat

    JS中的面向对象 最最最开始,我们先来说说JS中的面向对象。 原型链 参考文章:图解Javascript原型链 J...

  • 前端面试准备--5.原型链

    *原型链(面向对象的一个基础) 1.创建对象有几种方法 2.原型、构造函数、对象实例、原型链 3.instance...

  • Javascript面向对象之组件

    高级面向对象 包装对象(13) js基于原型的程序 String Number Boolean 原型链(14) 实...

  • 面向对象、原型、原型链

    构造对象方式 字面量的方式 问题 太麻烦了,每次构建一个对象都是复制一遍代码 如果想个性化,只能通过手工赋值,使用...

  • 面向对象&原型&原型链

    1、js对象就是系列key:value的组合,面向对象编程在大部分编程语言中都有所提及,其基本思想是将某个功能看成...

  • JavaScript原型链

    js原型链 原型链是JS面向对象的基础非常重要 所有对象只有__proto__属性,而函数具有prototype属...

网友评论

      本文标题:lesson 5 面向对象及原型链 2021-04-29

      本文链接:https://www.haomeiwen.com/subject/eweirltx.html