资讯专栏INFORMATION COLUMN

JavaScript创建对象的5种模式

wemallshop / 1796人阅读

摘要:一工厂模式创建对象交给一个工厂方法来实现,可以传递参数,但主要缺点是无法识别对象类型,因为创建对象都是使用的原生构造函数来完成的。此外,组合模式还支持向构造函数传递参数,可谓是集两家之所长。

原文链接

面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装继承多态的特性!

但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义JS中对象:无序属性的集合,其属性可以包含基本值、对象或者函数。

可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。

一、工厂模式

创建对象交给一个工厂方法来实现,可以传递参数,但主要缺点是无法识别对象类型,因为创建对象都是使用Object的原生构造函数来完成的。

function createPerson(name, age, job) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.job = job;
  o.getName = function () {
    return this.name;
  }
  return o; // 使用return返回生成的对象实例
}
var person = createPerson("Jack", 19, "SoftWare Engineer");
二、构造函数模式
function Person(name,age,job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.getName = function () {
    return this.name;
  }
}
var person1 = new Person("Jack", 19, "SoftWare Engineer");
var person2 = new Person("Liye", 23, "Mechanical Engineer");

构造函数模式与工厂方法区别在于:

没有显式地创建对象

直接将属性和方法赋值给this对象

没有return语句

上述由Person构造函数生成的两个对象person1与person2都是Person的实例,因此可以使用instanceof判断,并且因为所有对象都继承Object,因此person1 instanceof Object也返回真:

console.log(person1 instanceof Person); // true;
console.log(person2 instanceof Person); // true;
console.log(person1 instanceof Object); // true;
console.log(person2 instanceof Object); // true;
console.log(person1.constructor === person2.constructor); // ture;

虽然构造函数方式比较不错,但也存在缺点,那就是在创建对象时,特别针对对象的属性指向函数时,会重复的创建函数实例,以上述代码为基础,可以改写为:

function Person(name,age,job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.getName = getName;
}
function getName() {
  return this.name;
}
三、原型模式

JS中每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它是所有通过new操作符使用函数创建的实例的原型对象。

原型对象最大特点是,所有对象实例共享它所包含的属性和方法,也就是说,所有在原型对象中创建的属性或方法都直接被所有对象实例共享。

function Person() {}

Person.prototype.name = "Jack";
Person.prototype.age = 29;
Person.prototype.getName = function () {
  return this.name;
}

var person1 = new Person();
var person2 = new Person();

console.log(person1.getName === person2.getName); // ture;
四、组合构造函数及原型模式

目前最为常用的定义类型方式,是组合构造函数模式与原型模式。

构造函数模式用于定义实例的属性,而原型模式用于定义方法共享的属性

这样,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方方法的引用,最大限度的节约内存。此外,组合模式还支持向构造函数传递参数,可谓是集两家之所长。

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.lessons = ["Math", "Physics"];
}
Person.prototype = {
  constructor: Person, // 原型字面量方式会将对象的constructor变为Object,需要强制指回Person
  getName: function () {
    return this.name;
  }
}

var person1 = new Person("Jack", 19, "SoftWare Engneer");
person1.lessons.push("Biology");

var person2 = new Person("Lily", 39, "Mechanical Engneer");

console.log(person1.lessons); // ["Math", "Physics", "Biology"]
console.log(person2.lessons); // ["Math", "Physics"]
console.log(person1.getName === person2.getName); // true
五、动态原型模式

组合模式中实例属性与共享方法(由原型定义)是分离的,这与纯面向对象语言不太一致。

动态原型模式将所有构造信息都封装在构造函数中,同时又保持了组合的优点。

其原理就是通过判断构造函数的原型中是否已经定义了共享的方法或属性,如果没有则定义,否则不再执行定义过程。

该方式只定义一次原型上方法或属性,且将所有构造过程都封装在构造函数中,对原型所做的修改能立即体现所有实例中:

function Person(name, age, job) {
  this.name = name;
  this.age = age;
  this.job = job;
  this.lessons = ["Math", "Physics"];
}
if (typeof this.getName) {
  Person.prototype = {
    constructor: Person, // 原型字面量方式会将对象的constructor变为Object,需要强制指回Person
    getName: function () {
      return this.name;
    }
  }
}
var person1 = new Person("Jack", 19, "SoftWare Engneer");
person1.lessons.push("Biology");

var person2 = new Person("Lily", 39, "Mechanical Engneer");

console.log(person1.lessons); // ["Math", "Physics", "Biology"]
console.log(person2.lessons); // ["Math", "Physics"]
console.log(person1.getName === person2.getName); // true

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81854.html

相关文章

  • 常用JavaScript设计模式你都知道吗?

    摘要:构造函数模式是中最常用的模式之一,用于创建给定类型的新对象。原型模式这是基于对象的创造型设计模式。它通常用于目标对象受到约束且可能无法有效地处理其所有职责的情况。它不是构造函数其静态方法用于可拦截的操作。 showImg(https://segmentfault.com/img/bVbwdpt?w=700&h=340); 原文:https://medium.com/better-pro...

    Jochen 评论0 收藏0
  • JavaScript设计模式》读后感 觉很复杂

    摘要:想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。创建型设计模式主要有简单工厂模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式和单例模式,下面一一道来。而工厂方法模式本意是将实际创建对象的工作推迟到子类中。 接触前端两三个月的时候,那时候只是听说设计模式很重要,然后我就去读了一本设计模式的书,读了一部分,也不知道这些设计模式到底设计出来干嘛的,然后就没再看了。后...

    e10101 评论0 收藏0
  • [译] 为什么原型继承很重要

    摘要:使用构造函数的原型继承相比使用原型的原型继承更加复杂,我们先看看使用原型的原型继承上面的代码很容易理解。相反的,使用构造函数的原型继承像下面这样当然,构造函数的方式更简单。 五天之前我写了一个关于ES6标准中Class的文章。在里面我介绍了如何用现有的Javascript来模拟类并且介绍了ES6中类的用法,其实它只是一个语法糖。感谢Om Shakar以及Javascript Room中...

    xiao7cn 评论0 收藏0
  • 【连载】前端个人文章整理-从基础到入门

    摘要:个人前端文章整理从最开始萌生写文章的想法,到着手开始写,再到现在已经一年的时间了,由于工作比较忙,更新缓慢,后面还是会继更新,现将已经写好的文章整理一个目录,方便更多的小伙伴去学习。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 个人前端文章整理 从最开始萌生写文章的想法,到着手...

    madthumb 评论0 收藏0

发表评论

0条评论

wemallshop

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<