JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象

一、仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下:

1、它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题!

2、最大的问题是原型中的所有属性是被很多实例所共享的,这种共享对于函数非常合适,对于那些包含基本值的属性也说得过去,因为我们知道可以在实例上添加一个同名属性,可以隐藏原型中的对应属性。但是对于包含应用类型值的属性来说,问题就非常严重了,代码如下:

function Person(){
}
Person.prototype={
    constructor:Person,
    name:"张三",
    age:22,
    job:"coder",
    friends:["李四","王五"],
    sayName:function(){
        alert(this.name);
    }
}
var person1=new Person();
var person2=new Person();

person1.friends.push("赵六");
    alert(person1.friends);  //输出:李四,王五,赵六
    alert(person2.friends);//输出:李四,王五,赵六

分析上面的代码,当我们为person1添加一个朋友的时候,发现person2同时也被添加了一个朋友,但这并不是我们想要的,而这正是因为原型模式的共享的本性所导致的,只要任何一个实例修改了原型属性对象中的属性值,所有与该原型对象关联的实例都会受到影响!

二、组合使用构造函数模式和原型模式

为了解决原型模式不能初始化参数和共享对于引用模式所存在的问题!这里我们可以采用构造函数模式和原型模式的结合模式来创建自定义类型,构造函数用于与解决初始化参数(实例属性的定义),原型模式用于共享  方法和constructor。

这种构造函数与原型组合的模式创建自定义类型,是ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

代码如下:

    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.friends=["小超","大超"];
    }
    Person.prototype={
        constructor:Person,
        sayName:function(){
            alert(this.name);
        }
    }
    var person1=new Person("张三",22,"coder");
    var person2=new Person("李四",22,"coder");
    person1.friends.push("Stephen Curry","Kevin Durant");
    alert(person1.friends); //输出:小超,大超,Stephen Curry,Kevin Durant
    alert(person2.friends);//输出:小超,大超

通过上面的输出我们发现组合使用构造函数模式和原型模式创建的自定义类型及解决了

1、构造函数:构造函数创建类型相同的函数,确是不同的作用域链和标识符解析(因为在JS中每创建一个函数就是一个对象,所以  (导致了构造函数中的方法)  在不同的实例中都需要重新创建一遍,但是这些方法做的确实同一件事情);

2、原型模式:其不能初始化参数,以及它的共享性对与一些引用类型所造成的影响(比如数组);

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阮一峰的网络日志

学习Javascript闭包(Closure)

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 下面就是我的学习笔记,对于Javascript初学者应...

2815
来自专栏闪电gogogo的专栏

Python入门学习(一)

看完了莫烦Python的视频,对于Python有了一点感觉,接下来打算把小甲鱼的视频啃完,附上学习网址:http://blog.fishc.com/catego...

3598
来自专栏惨绿少年

AWK常用技巧

awk其名称得自于它的创始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首个字母。实际上 AWK 的确...

1964
来自专栏小小挖掘机

这或许是我见过的最简单的正则表达式教程(二)

五一劳动节来啦,小小挖掘机们小编们首先祝大家劳动节快乐! 作为中国放假大学的一员,除了趁着长达8天的五一春假好好休整之外,当然还要忙中偷闲补习一下python的...

2704
来自专栏Fish

两天了解scala

最前面的话 因为spark的源语言是scala,所以,为了看懂spark的操作并且为了以后看spark源码做准备,先看scala还是很有必要的。另外这里主要是看...

2039
来自专栏python3

python for循环

当range执行完之后,代码执行else部分代码。如果遇到break,终止循环,不会走else代码

2441
来自专栏专注数据中心高性能网络技术研发

[Effective Modern C++(11&14)]Chapter 4: Smart Pointers

2752
来自专栏更流畅、简洁的软件开发方式

静态变量 静态对象 静态函数和非静态函数的区别。(我的理解,大家看看对不对)

先明确一下 语言:asp.net C# 1、静态变量: static string str1 = "1234"; 2、静态对象 static SqlConn...

2235
来自专栏大前端_Web

jsvascript—谜之this?

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

1664
来自专栏mukekeheart的iOS之旅

OC学习6——面相对象的三大特性

我们在学习Java的时候都知道,类有三大特性:继承,封装,多态,这也是面向对象的三大特征。OC学习篇之---类的三大特性(封装,继承,多态) 1、封装(Enca...

2828

扫码关注云+社区

领取腾讯云代金券