创建对象的6种方式详解

总结一下创建对象的几种方案:

1.字面量创建

let Person={};
let Person={
    name:"Jason",
    age:21
}

开发的过程中最常见的方式,简单方便,内聚性强。

2.new Object()

var Person =new Object();
Person.name = 'Jason'
Person.age = 21
上面这两种方式,创建同样的对象时,需要编写重复的代码。

3.使用工厂模式创建对象

function createPerson(name, age, height, address) {
  var p = {}
  p.name = name
  p.age = age
  p.height = height;
  p.address = address
  p.eating = function() {
    console.log(this.name + "在吃东西~")
  }
  p.running = function() {
    console.log(this.name + "在跑步~")
  }
  return p
}

var p1 = createPerson("张三", 18, 1.88, "广州市")
var p2 = createPerson("李四", 20, 1.98, "上海市")
var p3 = createPerson("王五", 30, 1.78, "北京市")

// 工厂模式的缺点(获取不到对象最真实的类型)
console.log(typeof p1) //object

       在使用工厂模式创建对象的时候,可以将创建对象的逻辑封装在一个函数里面,避免了重复代码,但是通过工厂函数创建的对象都是object类型,如果希望创建出来的对象有一个共同的类型,于是就出现了第四种创建对象的模式

4.使用构造函数创建对象

// 规范: 构造函数的首字母一般是大写
function Person(name, age, height, address) {
  this.name = name
  this.age = age
  this.height = height
  this.address = address

  this.eating = function() {
    console.log(this.name + "在吃东西~")
  }

  this.running = function() {
    console.log(this.name + "在跑步")
  }
}
var p1 = new Person("张三", 18, 1.88, "广州市")
var p2 = new Person("李四", 20, 1.98, "北京市")
console.log(p1 instanceof Person) //true
console.log(p2 instanceof Person) //true
console.log(p1 instanceof Object) //true
console.log(p2 instanceof Object) //true

通过构造函数可以确保创建出来的对象都具有相同的类型

但是这种方式也存在缺陷:

每个对象里面都有公用的函数,意味着每次创建一个对象都会创建一个函数实例,因此可以这个函数放到外面,但是会污染全局作用域。

就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法

5.原型创建对象模式

function Person(){}
Person.prototype.name = 'Nike';
Person.prototype.age = 20;
Person.prototype.firends= [];
Person.prototype.sayName = function(){ alert(this.name);};
let person1 = new Person()
person1.name = '哈哈' //往person1上面新增了name属性
person1.friends.push('kobe') //会修改原型上的值,所有的实例都会受到影响
let person2 = new Person()
console.log(person2.friends) // ['kobe']

这种方式将对象的属性和方法都保存到函数的原型上,创建出来的所有实例都可以访问到原型上的属性和方法,而不用在每个对象上都保存一份函数实例。

缺点:

1.这些属性并没有保存到对象自身上,而是通过原型链去访问

2.如果修改了name属性,相当于在person1上面新增了属性name

3.如果修改了一个引用数据类型,则会修改原型上面的值,所有的实例都会收到影响

6.组合使用构造函数模式和原型模式

function Person(name, age, height, address) {
  this.name = name
  this.age = age
  this.height = height
  this.address = address
}

Person.prototype.eating = function() {
  console.log(this.name + "在吃东西~")
}

Person.prototype.running = function() {
  console.log(this.name + "在跑步~")
}

var p1 = new Person("why", 18, 1.88, "北京市")
var p2 = new Person("kobe", 20, 1.98, "洛杉矶市")

p1.eating()
p2.eating()

实例属性都是在构造函数中定义的,而所有实例方法则是在原型中定义。

        这种模式是ECMAScript中使用最广泛,认可度最高的一种创建自定义类型的方法,可以说这是用来定义引用类型的一种默认模式。

你可能感兴趣的:(JavaScript学习笔记,javascript,前端,开发语言)