原型对象也不是没有缺点。首先,它省略了为构造函数传递初始化参数这一环节, 结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便, 但还不是原型对象的最大问题。原型对象的最大问题是由其共享的本性所导致的。
原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说得过去,毕竟(如前面的例子所示),通过在实例上添加个同名属性, 可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出了。来看下面的例子。

function Person() {}

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

在此,Person.prototype对象有一个名为frends的属性,该属性包含一个字符串数组。然后,创建了Person的两个实例。接着修改了person1.friends引用的数组,向数组中添加了一个字符串。由于friends数组存在于Person.prototype而非person1中,所以刚刚的修改也会通过person2.friends(与person1.friends指向同一个数组)反应出来。假如我们的初衷就是像这样在所有实例中共享一个数组,那就没什么好说的。可是,实例一般都是要有属于自己的全部属性的。而这个问题正是我们很少看到有人单独使用原型的原因。

创建自定义类型的最常见方式,就是组合使用构造函数与原型。构造函数用于定义实例属性,而原型用于定义方法和共享的属性。结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存。下面的代码重写了前面的例子。

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"); person1.friends.push ("Van");
alert(person1.friends); //"Shelby, Count ,Van"
alert(person2.friends); //"She1 by,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName); //true

在这个例子中,实例属性都是在构造函数中定义的,而由所有实例共享的属性constructor和方法sayName()则是在原型中定义的。而修改了person1.friends (向其中添加一个新字符串),并不会影响到person2.friends,因为它们分别引用了不同的数组。
这种构造函数与原型混成的模式,是目前在ECMAScript中使用最广泛、认同度最高的一种创建自定义类型的方法。可以说,这是用来定义引用类型的一种默认模式。

JavaScript 原型链学习(三)原型对象存在的问题 与 组合使用构造函数和原型的更多相关文章

  1. JavaScript 原型链学习(四)原型链的基本概念、原型链实现继承

    简单回顾一下构造函数.原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.那么,假如我们让原型对象等于另一个类型的实例,结果会 ...

  2. javascript原型原型链 学习随笔

    理解原型和原型链.需从构造函数.__proto__属性(IE11以下这个属性是undefined,请使用chrome调试).prototype属性入手. JS内置的好多函数,这些函数又被叫做构造函数. ...

  3. JavaScript 原型链学习(一)原型对象

    在JavaScript中创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有的实例共享的属性和方法.如果按照字面意思来理解 ...

  4. JavaScript原型(链)学习笔记

    javascript是基于原型的一门脚本语言,那究竟原型是什么? 本文将从以下几个方面重点阐述原型 构造函数是什么? 构造函数和我们常见的Array String有什么关系? 原型的使用? __pro ...

  5. JavaScript原型与原型链学习笔记

    一.什么是原型?原型是一个对象,其他对象可以通过它实现属性继承.简单的说就是任何一个对象都可以成为原型 prototype属性: 我们创建的每个函数都有一个prototype属性,这个属性是一个指针, ...

  6. javaScript 原型与原型链学习笔记

    javaScript中,原型是常用到一种方式,它能降低储存占用,写出更高效的代码 原型常用到的则是prototype属性 JavaScript prototype 属性 定义和用法 prototype ...

  7. JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍

    1.原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct.Array.String等等)都在构造函数的原型上定义方法和属性.如下代码可以证明: alert(typeo ...

  8. JavaScript 原型链学习(二)原型的动态性

    由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来,即使是先创建了实例后修改原型也照样如此.如下示例: var friend = new Person(); ...

  9. JS 原型链学习总结

    废话篇: 在js的学习过程中有一大难点就是原型链.学习的时候一直对这一内容不是十分的明白.纠结的我简直难受.,幸好总算给他弄通了,哇咔咔,总算可以不用在睡梦中还想着他了. 正文篇: 要了解原型链我们首 ...

随机推荐

  1. tensorflow, TypeError:'Tensor' object is not callable

    解决办法:两个tensor相乘,需要加“*”.

  2. jsp 连接access数据库

    参考笔记:https://www.cnblogs.com/mthoutai/p/7278995.html

  3. js 零散知识总结

    网页播放声音 这个非常简单,我们只需要在html和js设置即可.首先看html代码 html代码 <audio id="sound" autoplay="autop ...

  4. CentOS安装和配置Apache(httpd)

    1. 安装httpd yum install httpd #安装apache 2. 启动httpd systemctl start httpd.service #启动apache 3. 随服务器自启动 ...

  5. 基于FeignClient提供简单的用户查询服务

    前言: 由于系统升级,之前的员工数据库(mongo库)被弃用,改为用python维护的mysql库,其他系统访问通过http请求,表结构对外不可见,其他系统之前对员工mongo库的依赖要解除.每套系统 ...

  6. vs启动出错(chenlu-1):参数“basePath”不能是相对路径

    参数“basePath”不能是相对路径 原因: 1.调试路径下没有exe文件.没有生成exe文件. 2.项目属性->配置属性->调试->命令中的参数被设置为相对路径.

  7. MQTT 嵌入式端通讯协议解析(转)

    MQTT,目前物联网的最主要的协议,基本所有收费的云平台都是基于MQTT协议,比如机智云,和所有的开放云平台比如中国移动的oneNet.百度的云平台也都支持MQTT的接入.虽然MQTT很火,但是目前对 ...

  8. kaggle竞赛-保险转化-homesite

    时间格式的转化 查看数据类型 查看DataFrame的详细信息 填充缺失值 category 数据类型转化 模型参数设定 结论 该项目是针对kaggle中的homesite进行的算法预测,使用xgbo ...

  9. 3.nodejs(三) 常用API

    1.querystring querystring: --- > qs npm i qs ==> qs:parse/stringify第三方插件,只有一个参数 JSON.parse  字符 ...

  10. Java高并发系列 — AQS

    只懂volatile和CAS是不是可以无视concurrent包了呢,发现一个好链接,继续死磕,第一日: 首先,我承认很多时候要去看源码才能更好搞懂一些事,但如果站在巨人肩膀上呢?有了大概思想源码看还 ...