zoukankan      html  css  js  c++  java
  • JavaScript面向对象

    概念

    • OO:Object Oriented(面向对象,详细概念见区别)

    • OOP(Program)面向对象编程

    • OOD(Design)面向对象设计

    • OOA(Analysis)

    区别

    • 面向过程

      • 关注方法步骤
      • 在分析问题时,提取出解决问题的方法和步骤,然后通过函数一步步实现,并依次调用
    • 面向对象(实质是对面向过程的进一步抽象)

      • 关注对象本身
      • 把要解决的问题中的数据和方法组织为一个整体(对象)来看待,是我们对现实事物的抽象。
    • 注意:

      • 面向过程和面向对象这两种编程方式,都是用来编写程序,解决我们实际需求以及问题的。
      • 二者示例对比:开车
        • 面向过程的开车:先打开车门,上车,系好安全带,把车钥匙插入,点火。。。。
        • 面向对象的开车:找一个司机,开车

    基本构成

    • 对象(具体)

      • 问题域中关注的具体的某一事物(对象因关注而产生)
    • (抽象)

      • 具有相同性质和行为的一组对象的抽象(分类)
      • 在代码中起“模具”作用
      • 大驼峰命名是类的标志(注意:并不是说只要大驼峰命名就是类,或者不使用大驼峰命名就不是类了,只是一种标志,便于开发者区分)
    • 关系:类是对象的抽象,对象是类的实例。

      • 所有对象都是类创建的,所以对象又称为实例对象。用类创建对象的过程叫做实例化。

    ES6语法糖

    //ES6 class----模版
            class Person {
                constructor(name, age, gender) {
                    this.name = name;
                    this.age = age;
                    this.gender = gender;
                }
                // name = "张三";
                // age = "18";
                //gender="男";
                eat() {
                    console.log(this.name);
                }
            }
            // 生成对象----模版---->实例
            let p1 = new Person("张三",18,"男");
            let p2 = new Person("里斯",13,"女");
            let p3 = new Person("王五",17,"男");
    
    • 只能使用new关键字调用,不能像普通函数那样调用,会报错。
    • class声明的类有暂时性死区,不能在声明前调用。

    ES5原理分析

    //将ES6语法糖还原为ES5原理
    function Person {//构造函数,内部写属性
    	this.name = name;
    	this.age = age;
    	this.gender = gender;
    }
    
    //方法放在构造函数身上的原型对象prototype上
    Person.prototype.eat=function(){
        console.log(this.name);
    }
    
    // 生成对象----模版---->实例
    let p1 = new Person("张三",18,"男");
    let p2 = new Person("里斯",13,"女");
    let p3 = new Person("王五",17,"男");
    
    • typeOf类-------->"function"
      • 说明类就是函数(构造函数)
      • 如何判断一个函数是普通函数还是类(构造函数),本质上是由调用函数的形式决定
        • 普通调用Person()
        • 使用new关键字进行调用new Person()
    • 属性和方法
      • 实例属性(私有)
        • 在构造函数内部以this.xxx=xxx;的方式进行创建
      • 公有属性
      • 方法
        • 公有属性和方法,统一放在类.prototype这个原型对象上,这里就是公共区域。
    • 类是通过JS函数模拟出来的,JS原本就不是面向对象的语言,是因为有了大量的需求才模拟出了类。
    • 使用new关键字调用时,究竟发生了什么
      • 创建一个新对象
      • 将新对象身上的__proto__指向创建该对象的构造函数身上的prototype
      • 将构造函数(类)内部的this指向刚刚创建的实例对象
      • 执行代码,将新对象作为返回值返回
    • 注意:
      • class声明的类有暂时性死区,不可在声明前使用。

    补充知识

    Object上的方法
    • Object.assign(),整合函数
    this指向
    • 箭头函数没有自己的arguments和this,this的指向问题,取决于它所处的环境。
      • 由于箭头函数没有this,所以不能作为构造函数。
      • 箭头函数的this一旦确定下来,就不会再改变了。
    • 事件监听器中的this,指向绑定事件的元素节点。
    • 构造函数内部的this,指向刚刚创建的实例对象。
    • 普通函数调用时,this一般指向window,但在严格模式下指向undefined。
      • 严格模式:就是在某个执行上下文的第一句写“use strict”,就是指定该环境中使用严格模式。
    • 谁调用指向谁。
    函数上的方法(方法借用)
    • 立即执行
      • call
      • apply
    • 稍后执行
      • bind
    包装类
    • 目的:
    • 有哪些
      • String
      • Number
      • Boolean
    • 特点:自动装箱,自动拆箱
    toString和valueOf

    三大特征:

    封装(encapsulation)
    • 将数据和方法捆绑在一起(如函数、类(对象))就实现了“装”,将其私有化只能自己使用就是“封”(可利用闭包实现)。
    继承(inheritance)
    • 类与类之间的关系。子类继承父类所有的属性和方法,并且拥有自己独特的属性和方法。(即满足xxx是xxx的关系)
    多态(polymorphism)
    • 不同东西,对同一件事(行为)的表现形式不同。

    ES6继承(语法糖)

    关键字:extendes和super
    • extends

      • 表达继承关系,书写在要声明的类后面,后面是要继承的父类。
      • extends需与super搭配使用,如果写了构造函数,里面必须调用super(),否则会保存;如果没不写构造,JS会自动为我们写一个空的构造器,并自动调super();
    • super

      • super() 方法放在子类的构造函数中,只能调用一次,且必须放在this和return之前(最好写在构造函数第一行)。如果父类需要传参,小括号内为传入的实参。
    class Student extends Person{
        constructor(){
            super();//可传参,实参
            this.xxx=xxx;
            ......
        }
    }
    

    原型

    对象分类
    • 函数对象(typeOf---->”function“)
    • 其他对象(typeOf---->”object“)
    规则
    • 除箭头函数外,所有函数对象身上都有一个原型对象(prototype)。
    • 所有对象身上都有一个隐式原型对象(__proto__,一个引用),它指向创建该对象的构造函数身上的原型对象。
    • 原型对象通常是一个普通对象,说明它是Object类的实例,作为对象它身上也有__proto__这个隐式原型对象,指向创建它的构造函数Object身上的原型对象。
    • 所有原型对象(prototype)上都有一个constructor引用,指向该原型对象所在的构造函数。
    原型链
    • 实例对象,通过__proto__不断的反复向上寻找,会形成一个链条,这个链条是用来找属性的,如果在链条的头部(自己身上)没有找到,会在下一个节点继续找,直到找完整个链条。如果找完整个链条都没有找到,则结果为undefined。
    • 方法是特殊的属性,当一个属性的值为函数的时候,它就变成了方法。
    • 原型链的出口(顶端)是Object.prototype,它身上的__proto__指向null。
    • 原型链中,如果各原型对象上有相同的属性,那么前面原型对象的这个属性会覆盖后面的(多态的一种表现)
    • 区别:作用域链------>找变量

    继承原理(ES5)

    • 混合继承=方法借用(继承属性)+原型继承(将父类的原型插入子类的原型链)
      • 方法借用
        • call
        • apply
        • bind
      • 原型继承
        • Object.create()
    function Super(name, age) {//父类,超类
         this.name = name;
         this.age = age;
    }
    Object.assign(Super.prototype, {
         sleep() {
            console.log(`${this.name} is sleeping!`);
         }
    })
    
    //子类
    function Sub(name, age, gender) {
         Super.call(this, name, age);
        //以调用父类构造函数的形式,得到执行结果,将this绑定为当前的实例对象
        //普通调用时,this的指向window而不是当前实例对象,所以使用方法借用,绑定this的指向
         this.gender = gender;
    }
    //原型继承(插入父类的原型链,如果父类在子类的原型链上,那么子类及其实例对象都可以通过原型链找到父类身上方法)
    // 父类原型插入的位置,实例对象和子类之间不可,因为实例对象必须指向创建它的类的原型对象;Obj原型和null之间不可,规定Obj.prototype指向null.只能在子类原型和Obj原型之间插入
    。
    Sub.prototype = Object.create(Super.prototype);//以父类的prototype为原型,创建一个空对象,替换子类的prototype
    Sub.prototype.constructor = Sub;//由于空对象身上没有constructor引用,赋值
    //自己的方法
    Object.assign(Sub.prototype, {
         eat() {
             console.log(`${this.name} is eating!`);
         }
    });
    let sub1 = new Sub("zs", 18, "male");
    // sub1.constructor===>fn Sub//sub1通过自己身上的__proto__指向创建它的类的原型对象 //Sub.prototype,prototype身上有它所在的构造函数的引用constructor
    //sub1.__proto__.constructor====>fn Sub
    

    多态

    • 重载:JS自带,传入不同的参数,实现效果不同(如if...else if语句)
    • 重写(覆盖):继承并覆盖父类的方法

    类的判断方法

    • instanceof
      • 作用:判断复杂数据类型的类型(是哪个类创建的)
      • 语法:要判断的对象 instanceof 类------->true/false
      • 原理:通过原型链来实现判断(即在该对象原型链上所有经过的类都会判断为true,并不是只要它的父类)
    • 区别:typeof------>判断基本数据类型的类型

    ES6 不常用语法

    属性的定义方法

    • 已知的定义方法

      let person={
      	name:"zs"
      }//声明式
      
      person.age=18;//直接赋值
      
    • Object.defineProperty()

    数据类型:

    • 为什么要进行复杂数据类型判断
      • 传参时传入对象
      • 判断传入的对象到底是什么再决定代码如何执行

    JS中

    • 基本数据类型6种(number、string、boolean、undefined、null、symbol)

      • typeof判断基本数据类型的类型
    • 复杂数据类型1种(object)

      • 但是有无数个类(object是他们的顶层表现)
      • typeof复杂数据类型:object、function
      • instanceof判断当前对象是由哪个类创建的
    • JS是弱类型语言:声明变量时,没有定义变量的数据类型,而是根据赋给变量的值的类型来决定它的数据类型。

      • 缺点:由于不知道声明变量要存储的数据类型,尽可能分配到使所有数据类型都能存放下的内存,会造成内存浪费,降低性能。
      • 优点:程序员友好型,不容易报错
    • 其他强类型语言:C,C++,Java等

      • 声明变量时就规定了变量存储的数据类型,只能存储相应类型的数据,否则会报错
      • 优点:根据不同的数据类型,给变量分配不同的内存,精细化内存管理,提高代码性能
      • 缺点:对程序员不友好,需要记忆大量内容,容易报错
    • 抛出错误

      • JS中错误也是个对象
      • throw new Error(".........")
      try{
          throw new Error(".........")
      }catch(e){
          console.log(e);//e就是try里面抓住的错误
      }finally{
          
      }
      //三个一起用,类似于if...else的关系
      
    • JS中万物皆对象

  • 相关阅读:
    wxPython
    IT从业者职业规划
    成功开发iPhone软件的10个步骤
    开源认识:Jumony
    一个GG/MM的彩色验证码图片(C#)
    IT从业者学习规划
    为某一个对象动态添加属性
    .net 动态加载css与js
    文本框等css
    博客园配合得很好的代码插件
  • 原文地址:https://www.cnblogs.com/Lotus3904/p/12500331.html
Copyright © 2011-2022 走看看