JS创建对象的几种方式

1:对象字面量

var foo = {
        age:10
};

2:通过Object构造函数

var foo = new Object()
foo.age = 10;

3:通过Object.create创建

let foo = {
     age:10
 };
 let f = Object.create(foo);
 console.log(f.age);//10

以上创建对象的缺点:
这三种方式,当需要创建多个对象时,会产生大量重复代码

4:通过工厂模式

  function createPerson(age) {
      let obj = new Object();
      obj.age = age;
      return obj;
  }

  let person = createPerson(10);

通过工厂的方式可以节省大量重复代码,但无法识别对象的类型, 即通过instanceof无法判断具体属于哪个实例,因为通过工厂模式创建的对象都属于Object的实例

5:构造函数模式

  function foo() {
      this.age = 10;
      this.run = function () {
          console.log(this.age)
      }
  }
  let f = new foo();
  console.log(f instanceof foo); //true
  console.log(f instanceof Object); //true

通过构造函数创建的对象,可以识别出具体从哪里构造出来的,但构造函数内的方法会被重复创建,造成内存空间的浪费

原型模式

  function Foo() {

  }
  Foo.prototype.age = 10;
  Foo.prototype.run = function () {
      console.log(this.age)
  };
  let f = new Foo();
  f.run(); //10

通过原型模式创建的对象,可以让所有的实例对象共享原型的属性和方法,并且因为原型上属性是共享的,所有很不方便维护

构造函数和原型组合模式

  function Foo(age) {
      this.age = age;
  }
  Foo.prototype= {
      //原型对象都有constructor属性(指针):它指向该原型对象的构造函数
      constructor:Foo,
      PI:3.14,
      run:function () {
          console.log(this.age)
      }
  };
  let f = new Foo(10);
  f.run(); //10
  console.log(Foo.prototype.constructor == Foo); //true

推荐使用,通过构造函数定义每个实例对象的私有属性,通过原型定义公有方法和属性,不仅节省了内存,也可以向构造函数传递参数

为什么要在原型上添加constructor:Foo?
因为原型对象的constructor默认是指向原型对象的构造函数,所以当我重写了Foo的prototype原型对象时, Foo.prototype原型对象上是没有constructor属性,会继续往父级原型链上查找,最终会是ƒ Object() { [native code] } 而按照约定,需要让constructor指向原型对象的构造函数,所以需要添加 constructor:Foo,如果不添加则 console.log(Foo.prototype.constructor == Foo); 结果为false,但也并不影响使用。

你可能感兴趣的:(前端)