zoukankan      html  css  js  c++  java
  • js创建对象的几种方式

    JS创建对象的几种方式

    一.直接创建(不推荐)

    字面量:

    var o1 = {
      name:'xiaoming',
      age:20,
      sayHi:function(){
        console.log("Hi");
      }
    }
          
    console.log(o1)
    console.log(o1 instanceof Object)   //true

    new操作符:

    var o2 = new Object();
    o2.name = 'xiaoming';
    o2.age = 20,
    o2.sayHi = function(){
      console.log("Hi");
    }
    
    console.log(o2)
    console.log(o2 instanceof Object) //true

    这种创建方式的缺点显而易见,每创建一个对象,都需要设置每一个属性,造成大量代码重复。

    二.工厂模式

    function cStudent(name,age) {
      var o = new Object();
      o.name = name;
      o.age = age;
      o.sayHi = function () {
        console.log("Hi");
      }
      return o;
    }
    
    var o3 = cStudent('xiaoming',20);
    var o4 = cStudent('xiaomei',18);
    console.log(o3 instanceof Object) // true

    工厂模式解决了上述代码重复的问题,但是不知道当前对象是什么类型,因为全部都是Object。

    三.构造函数

    function Student(name,age) { //为了区别普通函数,构造函数名开头大写
      this.name = name;
      this.age = age;
      this.sayHi = function () {
        console.log("Hi");
      }
    }
    
    var o5 = new Student('xiaoming',20);
    var o6 = new Student('xiaomei',20);
    
    console.log(o5.__proto__ == o6.__proto__)  //true
    console.log(o5.age == o6.age)  //true
    console.log(o5.sayHi == o6.sayHi)  //false

    可以看到,o5和o6的原型对象是相同的,属性age也是相同的,但是sayHi的方法是不同的。也就是说构造函数的实例对象可以继承属性,但是不能继承方法。

    四.原型模式

    function Person() {}
    Person.prototype.name = 'xiaoming';
    Person.prototype.age = 20;
    Person.prototype.sayHi = function () {
      console.log('hi')
    }
    
    var o7 = new Person();
    var o8 = new Person();
    console.log(o7.sayHi == o8.sayHi) //true

    这里将sayHi方法添加到了Person的原型对象上,所以o7和o8访问的都是同一组属性和同一个sayHi()函数。由此衍生出混合模式

    五.混合模式(推荐)

    function Student(name,age) {
      this.name = name;
      this.age = age;
    }
    
    Student.prototype = {
      constructor:Student,
      sayHi : function () {
        console.log('Hi')
      }
    }
    
    var o9 = new Student('xiaoming',20);
    var o10 = new Student('xiaomei',20);
    
    console.log(o9.age == o10.age) //true
    console.log(o9.sayHi == o10.sayHi) //true

    可以看出,混合模式共享着对相同方法的引用,又保证了每个实例有自己的私有属性。最大限度的节省了内存。

    六.动态原型模式

    function Student(name,age) {
      this.name = name;
      this.age = age;
      if(typeof this.sayHi != "function"){
        Student.prototype.sayHi = function () {
          console.log('Hi')
        }
      }
    }
    var o11 = new Student('xiaoming',20);
    var o12 = new Student('xiaomei',18);
    
    console.log(o11.sayHi == o12.sayHi) //true

    这里只在sayHi()方法不存在的情况下,才会将它添加到原型中。

    七.Object.create

    // new Object() 方式创建
    var a = {  rep : 'apple' }
    var b = new Object(a)
    console.log(b) // {rep: "apple"}
    console.log(b.__proto__) // {}
    console.log(b.rep) // {rep: "apple"}
    
    // Object.create() 方式创建
    var a = { rep: 'apple' }
    var b = Object.create(a)
    console.log(b)  // {}
    console.log(b.__proto__) // {rep: "apple"}
    console.log(b.rep) // {rep: "apple"}

    new Object() 通过构造函数来创建对象, 添加的属性是在自身实例下。
    Object.create() es6创建对象的另一种方式,可以理解为继承一个对象, 添加的属性是在原型下。

  • 相关阅读:
    基于k8s搭建微服务日志收集中心
    分析java堆内存满时那些类占用内存居多
    yizimi 在 DMG 的板子库 (数据结构与算法)
    Contest 3/14
    基础算法训练1
    图论基础训练
    2021.03.09随笔
    树莓派 4B 安装 openEuler
    Docker 学习准备
    关于备案第二个服务器时遇到的问题
  • 原文地址:https://www.cnblogs.com/wangyuyuan/p/13919538.html
Copyright © 2011-2022 走看看