面向对象编程

一件事情无论太晚或者太早,都不会阻拦你成为你想成为的那个人,这个过程没有时间的期限,只要你想,随时都可以开始
-- 本文章来自拉勾大前端

面向对象编程

  • 对象是单个事物的抽象
  • 对象是一个容器,封装了属性和方法

什么是对象

  • 对象是一个概念,可以简单理解为:数据集或功能集
  • 把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数

面向对象编程

  • 每个对象都是功能中心,可以完成接受信息、处理数据、发出信息等任务
  • 面向对象编程具有灵活、代码可复用、高度模块化等特点,容易维护和开发,比起由一系列函数或指令组成的传统的过程式编程更适合多人合作的大型软件项目
      //抽象出Class
      function Student(name,score){
        this.name = name;
        this.score = score;
        this.printScore = function (){
          console.log("姓名:" + this.name + ";成绩:" + this.score);
        }
      }
      //根据Class创建实例
      var std1 = new Student("Bob",89);
      // 指挥实例得出结果
      std1.printScore();
    

创建对象的几种方式

  • new Object()构造函数
  • 对象字面量{}
  • 工厂函数
  • 自定义构造函数

constructor

  • 构造器和构造函数
  • 每个对象的constructor属性值就是生成这个对象的构造函数
  • console.log(obj.constructor);
  • 判断一个对象的具体对象类型需要使用instanceof进行判断
    console.log(obj1 instanceof Obj);
    

构造函数和实例对象的关系

  • 构造函数是根据具体事物抽象出来的抽象模板
  • 实例对象是根据抽象的构造函数模板得到的具体实例对象

静态成员和实例成员

  • 使用构造函数创建对象时,可以给构造函数创建实例对象添加属性和方法,这些属性和方法都叫成员
  • 实例成员: 在构造函数内部添加给this的成员
  • 静态成员: 添加给构造函数自身的成员
function Person(name,age){
      this.name = name;
      this.age = age;
      this.type = "man";
      this.sayName = fns.sayName;
      this.sayAge = fns.sayAge;
    }
    var fns = {
      sayName : function (){
        console.log(this.name);
      },
      sayAge : function (){
        console.log(this.age)
      }
    }o
    var per1 = new Person("Bob",18);
    per1.sayName();

prototype 原型对象

  • 任何函数都有一个prototype属性,该属性是一个对象
  • 可以在原型上添加属性和方法
  • prototype默认有个constructor属性,指向prototype对象所在函数
  • 通过构造函数得到的实例对象内部会包含一个指向构造函数prototype对象的指针proto
  • 实例对象可以直接访问原型对象成员
 function Person(name, age){
    this.name = name;
    this.age = age;
  }
  // console.log(Person.prototype.constructor);
  Person.prototype.type = "man";
  Person.prototype.sayName = function (){
    console.log("hello");
  }
  // console.log(Person.prototype.constructor);
  var per1 = new Person("Bob",14);
  // per1.sayName();
  console.log(per1.__proto__);
  console.log(per1.constructor); 
  per1.sayName();
  • 每一个构造函数都有一个prototype属性,指向构造函数的原型对象,这个对象的所有属性和方法都会被构造函数实例对象所拥有,因此,我们把所有对象实例需要共享的属性和方法直接定义在prototype对象上
    rl1FnP.png

原型链查找机制

  • 每当代码读取某个对象的某个属性时,都会执行一次搜索,首先从对象实例本身开始查找,如果没找到继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性,如果在原型对象中找到这个属性,则返回该属性的值

实例对象读写原型对象成员

  • 值类型成员写入(实例对象.值类型成员 = xx)
  • 引用类型成员写入(实例对象.引用类型成员 = xx)

复杂类型成员修改

  • 同样在自身去找该成员,如果身上找到则直接修改
  • 如果身上找不到,则沿着原型链继续查找,找到则修改
  • 如果到原型链末端还没有找到该成员,则报错

更简单的原型语法

  • 前面在原型对象每添加一个属性和方法就要书写一遍Person.prototype
  • 用一个包含所有属性和方法的对象字面量来重写整个原型对象,原型对象会丢失constructor成员,所以需要手动将constructor指向正确的构造函数
    Person.prototype = {
      //记到添加constructor
      constructor : Person,
      type : "man",
      sayName : function(){
        console.log(this.name);
      }
    }
    

原型对象使用建议

  • 私有成员(非函数成员)放到构造函数中
  • 共享成员(函数)放到原型对象中
  • 如果重置了prototype记得修正constructor的指向

你可能感兴趣的:(面向对象编程)