zoukankan      html  css  js  c++  java
  • JavaScrip构造函数

    构造函数

    工厂函数

    工厂函数是一种特殊的函数,其目的是为了简化对象的创建

    let createPerson = (name, age) => {
        return {
            name: name,
            age: age,
            say: function (){
              // ...
            }
        }
    }
        
    let p = createPerson('zs', 18);
    

    构造函数

    构造函数与工厂函数一样都是为了简化对象的创建,构造函数本质就是工厂函数的简化

    构造函数与工厂函数的不同:

    • 构造函数的函数名首字母必须大写
    • 构造函数不能直接调用,必须使用new关键字
    function Person (name, age){
        // let obj = new Object();
        // let this = obj;
        
        this.name = name;
        this.age = age;
        this.say = function (){
          // ...
        }
            
        // return obj;
        // 省略部分是JavaScript在执行过程中自行添加的
    }
        
    let p = new Person('zs', 18);
    

    ES6中的构造函数

    class Person(){
        constructor(name, age){
            // 构造函数中的代码块会在每次通过 new 创建对象时自动执行
            // 构造函数中的属性以及方法在每次创建对象时,都会在内存中重新开辟一块区域存放,每个实例对象之间的属性及方法相互独立、互不干扰
            
            this.name = name;
            this.age = age;
            this.say = function (){
                // ...
            }
            
            Person.countNum();
        }
        
        // constructor 外部的内容就相当于构造函数原型对象(prototype)上的内容
        // 在定义类时,在 constructor 外部使用 static 关键字定义的属性、方法称之为静态属性、静态方法
        // 静态属性、静态方法只会在类定义时生成一次,之后创建实例对象时不会重复生成,提高了代码的运行效率
        // 静态属性、静态方法只能通过 类名.属性名、类名.方法名 调用
        
        static count = 0;
                
        static countNum(){
            Person.count++;
        }
    }
    
    let p1 = new Person();
    let p2 = new Person();
    
    console.log(p1.say === p2.say); // false
    console.log(Person.count); // 2
    

    构造函数中的三角关系

    • 每个构造函数内部都有一个prototype属性,这个属性中保存了一个对象,称之为原型对象
    • 每个原型对象内部都有一个constructor属性,这个属性指向这个原型对象的构造函数
    • 实例对象内都有一个__proto__属性,这个属性指向实例对象构造函数的原型对象
    function Demo(){
        // ...
    }
        
    let d = new Demo();
    
    console.log(Demo.prototype.constructor === Demo); // true
    console.log(d.__proto__ === Demo.prototype); // true
    
    

    Function对象以及Object对象

    • Function构造函数是所有函数(包括构造函数)的祖先函数
    • Function构造函数的__proto__指向自身的原型对象
    • Object构造函数是所有自定义对象以及Function对象的祖先函数
    • Object构造函数的原型对象的__proto__指向 Null

    原型链

    原型链:在JavaScript中,当调用实例对象的属性或方法时会先从对象自身来查询;如未查询到则会沿着对象__proto__的指向依次查询,直到找到Object原型对象仍未找到时,由于Object原型对象的__proto__指向Null,则会报错。

    封装 、继承、多态

    • 封装

      • 当一个类将自身的成员变量暴露给外界,它就失去了对成员变量的控制权,外界可以随意修改器内部属性。

      • 封装本质就是对外界隐藏内部细节,仅提供必要的访问接口,以保证内部数据不被外部随意篡改。

      • 封装是面向对象设计的本质(将变化隔离),降低了数据被误用的可能性,保证了充分的安全性以及灵活性。

        function Person(){
            let age = 20;
            
            // 通过 setAge 方法,保证内部属性的有效性
            this.setAge = num => {
                age = (num > 0 && num <= 120) ? num : age;
            }
        }
        
    • 继承

    继承就是将多个构造函数中共有的属性、方法提取出来放到父类函数中,从而减少代码的冗余度。

      // ES6中的继承
      class Person(){
          constructor(name, age){
              this.name = name;
              this.age = age;
              this.say = function(){
                  // ...
              }
          }
      }
      
      class Student extends Person{
          constructor(name, age, score){
              // 通过 super 方法可以快速调用父类的构造函数,从而精简子类构造函数
              super(name, age);
              this.score = score;
              this.exam = function(){
                  // ...
              }
          }
      }
    
    • 多态

      多态就是一种事物在不同环境下表现的状态不同

      • 在强类型语言(编译性语言,如 Java、c、c++)中,一般通过继承与多态来减少代码的冗余度
      • 在弱类型语言(解释性语言,如 JavaScript)中,由于变量的定义规则不严格,所以不需要使用多态

    原型对象、对象类型的判断

    • 获取对象类型

      // 构造函数中存在一个 name 属性,存放着构造函数的名称
      // 由于原型对象中不存在 constructor 属性,所以会沿着原型链找到父类的构造函数
      console.log(p.__proto__.constructor.name === p.constructor.name); // true
      
    • 判断对象是否是构造函数的实例

      // instanceof 关键字会从原型链中寻找,只要构造函数出现在了实例对象的原型链上就会返回 true,若是查找到 Null 仍未查找到则会返回 false
      
      class Person{
          // ...
      }
      
      class Student extends Person{
          // ...
      }
      
      let stu = new Student();
      
      console.log(stu instanceof Student);// true
      console.log(stu instanceof Person);// true
      console.log(stu instanceof Object);// true
      
    • 判断构造函数的原型对象是否为对象的原型对象

      // isPrototypeOf 关键字会从原型链中寻找,只要构造函数的原型对象出现在了对象的原型链上就会返回 true,若是查找到 Null 仍未查找到则会返回 false
      
      class Person{
          // ...
      }
      
      class Student extends Person{
          // ...
      }
      
      let stu = new Student();
      
      console.log(Student.isPrototypeOf(stu));// true
      console.log(Person.isPrototypeOf(stu));// true
      console.log(Object.isPrototypeOf(stu));// true
      
  • 相关阅读:
    BZOJ 2154 Crash的数字表格 莫比乌斯反演
    BZOJ 3529 SDOI2014 数表 莫比乌斯反演+树状数组
    bzoj 3527 [Zjoi2014]力
    【bzoj2194】快速傅立叶之二
    bzoj3160 万径人踪灭
    高精度乘法(FFT)
    【网络流24题】太空飞行计划
    奶牛通信
    关于点分治的理解
    0924解题报告
  • 原文地址:https://www.cnblogs.com/luwenfeng/p/11693740.html
Copyright © 2011-2022 走看看