JavaScript 原型链学习(三)原型对象存在的问题 与 组合使用构造函数和原型
原型对象也不是没有缺点。首先,它省略了为构造函数传递初始化参数这一环节, 结果所有实例在默认情况下都将取得相同的属性值。虽然这会在某种程度上带来一些不方便, 但还不是原型对象的最大问题。原型对象的最大问题是由其共享的本性所导致的。
原型中所有属性是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性倒也说得过去,毕竟(如前面的例子所示),通过在实例上添加个同名属性, 可以隐藏原型中的对应属性。然而,对于包含引用类型值的属性来说,问题就比较突出了。来看下面的例子。
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 原型链学习(三)原型对象存在的问题 与 组合使用构造函数和原型的更多相关文章
- JavaScript 原型链学习(四)原型链的基本概念、原型链实现继承
简单回顾一下构造函数.原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针.那么,假如我们让原型对象等于另一个类型的实例,结果会 ...
- javascript原型原型链 学习随笔
理解原型和原型链.需从构造函数.__proto__属性(IE11以下这个属性是undefined,请使用chrome调试).prototype属性入手. JS内置的好多函数,这些函数又被叫做构造函数. ...
- JavaScript 原型链学习(一)原型对象
在JavaScript中创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有的实例共享的属性和方法.如果按照字面意思来理解 ...
- JavaScript原型(链)学习笔记
javascript是基于原型的一门脚本语言,那究竟原型是什么? 本文将从以下几个方面重点阐述原型 构造函数是什么? 构造函数和我们常见的Array String有什么关系? 原型的使用? __pro ...
- JavaScript原型与原型链学习笔记
一.什么是原型?原型是一个对象,其他对象可以通过它实现属性继承.简单的说就是任何一个对象都可以成为原型 prototype属性: 我们创建的每个函数都有一个prototype属性,这个属性是一个指针, ...
- javaScript 原型与原型链学习笔记
javaScript中,原型是常用到一种方式,它能降低储存占用,写出更高效的代码 原型常用到的则是prototype属性 JavaScript prototype 属性 定义和用法 prototype ...
- JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍
1.原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct.Array.String等等)都在构造函数的原型上定义方法和属性.如下代码可以证明: alert(typeo ...
- JavaScript 原型链学习(二)原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来,即使是先创建了实例后修改原型也照样如此.如下示例: var friend = new Person(); ...
- JS 原型链学习总结
废话篇: 在js的学习过程中有一大难点就是原型链.学习的时候一直对这一内容不是十分的明白.纠结的我简直难受.,幸好总算给他弄通了,哇咔咔,总算可以不用在睡梦中还想着他了. 正文篇: 要了解原型链我们首 ...
随机推荐
- JavaScript之JS的数据类型
前言 JavaScript一共有6中数据类型: 基本数据类型(5):字符串(String).数字(Number).布尔(Boolean).数组(Array).空(Null).未定义(Undefined ...
- MongoDB学习总结(二)
前言:学习札记! MongoDB学习总结(二) 1. 安装.初识 之前写过一篇MongoDB的快速上手文章,里边详细的讲了如何安装.启动MongoDB,这里就不再累述安装过程,简单介绍一下Mongo ...
- easyui的tree节点的获取和选中
1.设置选中tree的节点 var node = $('#tt').tree('find', 1);//找到id为”tt“这个树的节点id为”1“的对象$('#tt').tree('select', ...
- Vue2学习笔记:计算属性(computed)
参考:https://www.cnblogs.com/zycbloger/p/6428907.html
- mybatis13--2级缓存
验证内置的2级缓存 Ehcache缓存的配置 01.引入需要的ehcache 和mybatis-ehcache 两个jar包 02.在mapper文件中增加 <cache type=" ...
- laravel5.4+vue+element简单搭建(gulp+laravel Elixir)(转)
如今laravel来到5.4版本,更方便引入vue了,具体步骤如下: 下图为我动到的文件 1.下载laravel5.4 2.命令行(laravel5.4目录下):composer install 3. ...
- springmvc02,使用注解
unit04_01 a.RequestMappingHandlerMapping组件 @RequestMapping("/login.do") 该标记用在Controller业务方 ...
- 20.react库 入门
vue插件: 使用方式:Vue.use(插件名称); {}/function 1.对象 export default { install(Vue,options){ } } 2.函数 export d ...
- 浅析 Hinton 最近提出的 Capsule 计划
[原文] 浅析 Hinton 最近提出的 Capsule 计划 关于最新的 Hinton 的论文 Dynamic Routing Between Capsules,参见 https:// ...
- java Api 读取HDFS文件内容
package dao; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; import java ...