javascript中常用的创建对象的方法工厂模式构造函数模式原型模式混合使用构造函数模式和原型模式小结

js中创建对象最简单的方法自然是直接new一个Object然后再为其添加属性和方法,例如一下代码:

var o = new Object();
o.name = "aaaa";
o.sayName = function() {
  alert(this.name);
}

但这样显然封装性太差,属性和方法分布在各个地方。 所以最容易想到的就是写一个函数来封装创建对象的过程,这就是设计模式中常用的工厂模式。 下面我们就先介绍一下工厂方法模式创建对象的方法


工厂模式

先直接上代码

function createStudent(no, name, age, class)
{
    var o = new Object();
    o.no = this.no;
    o.name = this.name;
    o.age = this.age;
    o.class = this.class;
    o.sayName = function() {
            alert(this.name);
    }
  return o;
}

var stu1 = createStudent(5,"chi",34,1);
stu1.sayName();

上述代码就很好的像我们展示了如何用工厂模式创建对象,我们可以重复调用这个函数创建对象,每调用一次就会根传进去的参数,创建一个新的对象。但工厂模式存在的问题是无法识别生成的是哪个对象。 而构造函数模式就可以很好的解决这个问题

构造函数模式

类似java语言和其他面向对象语言的构造函数,构造函数模式如下:

function Student(name,no,age,class)
{
  this.name = name;
  this.no = no;
  this.age = age;
  this.class = class;
  this.sayName = function() {
  alert(this.name);
  }
}

var stu1= new Student("Nicholas", 29,34,4); 

与工厂模式比较,我们发现构造函数模式,直接赋值给this,不用在函数内创建一个Object,也需要return语句。 在使用构造函数模式创建对象的时候,只需要跟其他面向对象语言一样使用new操作符即可。 实际上,js在使用构造函数模式创建对象的过程中有以下的几个步骤:

  • 创建一个新对象
  • 将对象的作用域赋给新对象
  • 调用构造函数中的代码为属性和方法赋值
  • 返回新对象 其中,我们发现js帮我们封装了1,2,4等步骤,我们只需要专注于创建对象的属性和方法就行了。 构造函数模式虽然好用,但也并非没有缺点。使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。在前面的例子中, stu1 和 stu2 都有一个名为 sayName()的方法,但那两个方法不是同一个 Function 的实例。 而实际上呢,我们只需要一个sayName函数的实例就行了,因为它们的作用都是一样的,如果按构造函数模式,就会造成很多无用的浪费。 由此,我们就引出了下一种的方法,原型模式

原型模式

原型对象简而言之,就是每个构造函数创建的对象都有一个指针,这个指针指向它的原形对象,而原形对象也和普通对象一样具有属性和方法,但不同的事,原形对象的属性和方法是让所有实例共享的,也就是它只有一份,谁需要,都是调用这一份副本,而不会反复创建。

function Person(){}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person(); 

prototype.PNG

这就是原型模式创建对象的方法,它可以通过共享来避免重复创建多余的函数。 但原型模式,显然存在一个问题就是,并不是所有东西都是共享的,所以实际中,我们常常将原型模式与工厂模式或者构造函数模式结合起来。联合使用。对于那些需要共享的属性和方法,我们就把它加入到原型对象中。

** 需要注意的是,如果实例对象和原型对象中的存在相同的属性和方法,那么js会先从实例中搜寻,如果找到了就忽略原型对象中的,如果在实例中没有找到,就继续到原型中寻找 **

混合使用构造函数模式和原型模式

创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。另外,这种混成模式还支持向构造函数传递参数;可谓是集两种模式之长。

function Person(name, age, job)
{
  this.name = name;
  this.age = age;
  this.job = job;
  this.friends = ["Shelby", "Court"];
}
Person.prototype = {
  constructor : Person,
  sayName : function(){
  alert(this.name);
  }
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor"); 

小结

以上就是js中主要用于创建对象的几种方法,工厂模式,构造函数模式,原型模式,构造函数模式和原型模式的组合使用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏儿童编程

一张图理清《梅花易数》梗概

学《易经》的目的不一定是为了卜卦,但是了解卜卦绝对能够让你更好地了解易学。今天用一张思维导图对《梅花易数》的主要内容进行概括,希望能够给学友们提供帮助。

32540
来自专栏儿童编程

《动物魔法学校》儿童学编程Scratch之“外观”部分

导读:本文通过一个案例《动物魔法学校》来学习Scratch语言的“外观”部分。之后通过一系列其他功能的综合运用对作品功能进行了扩展。

19440
来自专栏Ken的杂谈

【系统设置】CentOS 修改机器名

18430
来自专栏FSociety

SQL中GROUP BY用法示例

GROUP BY我们可以先从字面上来理解,GROUP表示分组,BY后面写字段名,就表示根据哪个字段进行分组,如果有用Excel比较多的话,GROUP BY比较类...

5.2K20
来自专栏儿童编程

我不是算命先生,却对占卜有了疑惑——如何论证“占卜前提”的正确与否

事出有因,我对《周易》感兴趣了很多年。只是觉得特别有趣,断断续续学习了一些皮毛。这几天又偶然接触到了《梅花易数》,觉得很是精彩,将五行八卦天干地支都串联了起来。...

15610
来自专栏儿童编程

声音功能让儿童编程更有创造性

导读:Scratch中声音功能非常强大,除了常规的音效,你甚至可以模拟各种乐器的各个发音、设置节拍、休止……如果你愿意,甚至可以用它创作一个交响乐。我们可以引导...

13940
来自专栏儿童编程

天干地支五行八卦的对应关系

19890
来自专栏haifeiWu与他朋友们的专栏

复杂业务下向Mysql导入30万条数据代码优化的踩坑记录

从毕业到现在第一次接触到超过30万条数据导入MySQL的场景(有点low),就是在顺丰公司接入我司EMM产品时需要将AD中的员工数据导入MySQL中,因此楼主负...

30940
来自专栏儿童编程

儿童创造力教育与编程教育的碰撞——MIT雷斯尼克教授最新理论梗概

儿童编程教育已经在我国各一线二线城市疯狂出现,颇有“烂大街”的趋势。我们不禁要问很多很多问题:

22670
来自专栏华章科技

穿越十年后看互联网+:家电行业的金矿在哪里?

现在市场上炒得火热的智能家居未来出路在何方?做智能家居的创业者应该注意哪些机会?传统家电厂商又到底如何借助互联网进行转型?本文以智能空调为例,用故事的形式,提前...

8410

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励