面向对象编程、原型及原型链

50 阅读2分钟

面向过程 和 面向对象

   import { track } from "Track";
   track = {
      init () {

      },
      sendLog () {}
   }
   track.init();
   const App = ({ name, type }) => {
      return (
         <div>
            <Child1 name={name} />
            <Child2 type={type} />
         </div>
      )
   }
   const Child1 = () => {
      useEffect(() => {
         track.sendLog()
      },[])
   }

面向过程

  • 描述的是一件事情的过程量,强调的是,我做完一件事情的全流程;

面向对象

  • 一切事物都是对象,对象是类的实例。
   class Person {
      constructor(name) {
         super(name);
      }
   }
   class Pig {
      getCooked() {
         return 'cooked';
      }
      getBigger() {
         return 'bigger';
      }
   }
   class Chief extends Person {
      cook();
   }
   class Consumer extends Person {
      eat();
   }
   class Consumer {}
   const pig = new Pig();
   const bigPig = pig.getBigger();
   const chief = new Chief();
   const luyi = new Consumer();
   const dinner = chief.cook(bigPig);
   luyi.eat(dinner);

实例:创建一个对象,有几种方法?

   Object.create(); // Object.create() 创建
   var b = {}; // 直接量创建
   var c = new Person(); // new 关键字创建

Object.create();

   const a = Object.create({});
   const b = {};
   const c = Object.create(Object.prototype);
   a.__proto__.__proto__ === Object.prototype;
   b.__proto__ === Object.prototype;

Object.create() 创建了一个对象 let a = Object.create(b); a 的原型指向 b 调用 a 对象的方法或者属性的时,a 上没有,会去 b 上找

   // hasOwnProperty 检查对象上是否有这个属性
   if(Object.prototype.hasOwnProperty) {
      return Object.prototype.hasOwnPrototype.call(obj,key)
   }

var b = {};

new 关键字

   function Car(name) {
      this.name = name;
   }
   // 在car原型上创建一个getName属性
   Car.prototype.getName = function() {
      console.log(this.name)
   }
   const c = new Car('haha');
   // new 创建的一个对象,这个对象的原型链指向 构造函数的原型
   c.__proto__ === Car.prototype;
   // 构造函数上,有个原型,里面有个 constructor 函数,就是这个构造函数本身
   Car.prototype.constructor = Car;
   // c 的构造函数 是 Car
   c.prototype === Car.prototype.constuctor === Car;

new 关键字 到底做了什么?

   创建了一个对象,这个对象的原型,指向了这个函数 Function 的 prototype;
   这个对象实现了这个函数的方法; 根据一些特定情况,返回对象;
      如果没有返回值,则返回创建的对象;
      如果有返回值,是一个对象,则返回这个对象;
      如果又返回值,不是一个对象,则返回创建的对象;
   // 实现一个 new 函数
   function newFunc(event) {
      if(typeof event !== 'function') {
         throw new Error('传入的参数必须是一个函数')
      }
      var obj = Object.create(event.prototype);
      var result = event.apply(obj, Array.prototype.silce.call(arguments,1));
      return (result && typeof result === 'object') ? result : obj;
   }
   // 实现 Object.create()
   function inherit(val) {
      if(val == null) throw TypeError();
      if(Object.create) {
         return Object.create(val);
      }
      var t = typeof val;
      if(t !== 'object' && t !== 'function') throw TypeError();
      function F() {};
      F.prototype = val;
      return new F();
   }

继承

   // 类继承
   class A extends B {}
   const c = new A(); // 实例

原型继承

   function Person(name) {
      this.name = name;
   }
   Person.prototype.getName = function() {
      console.log('name' + this.name)
   }
   function Teacrher() {};
   // 继承
   Teacrher.prototype = new Person();
   Teacrher.prototype.constructor = Teacrher;
   // 如果有属性是引用属性,则修改原型属性的时候,会修改原型链上所有实例的属性

构造函数继承

   function Person(name) {
      this.name = name;
   }
   Person.prototype.getName = function() {
      console.log('name' + this.name)
   }
   function Teacrher(name, age) {
      Person.apply(this, Array.prototype.slice.call(arguments, 1))
      this.age = age;
   }
   // 属性或者方法,想被继承,只能在构造函数中定义
   // 如果在构造函数中定义,每次构造都会被创建
组合寄生继承
   function inherit(subType, superType) {
      var prototype = Object.create(superType.prototype);
      prototype.constructor = subType;
      subType.prototype = prototype;
      return subType;
   }
   class SuperType {
      constructor(name) {
         this.name = name;
         this.colors = ['red', 'blue', 'green'];
      }
      sayName() {
         console.log(this.name);
      }
      sayColors() {
         console.log(this.colors);
         for (var i = 0; i < this.colors.length; i++) {
               console.log(this.colors[i]);
         }
      }
   }
   class SubType extends SuperType {
      constructor(name, age) {
         super(name);
         this.age = age;
      }
      sayAge() {
         console.log(this.age);
      }
   }

书籍

《你不知道的 JS》 - 上卷 《JS 权威指南》 《JS 高级程序设计》

方法

费曼技巧、艾宾浩斯记忆曲线