关于JavaScript中的创建对象的学习总结
一、最简单的对象创建方法
在JavaScript中,直接使用Object构造函数或对象字面量都可以很轻易地创建单个对象,缺点是:创建具有同一个接口(标准的OO中的接口概念)的多个对象时,会有大量重复代码。为解决这个问题,引出了工厂模式。
二、工厂模式
工厂模式是GoF的23中设计模式中比较简单的模式,简单总结就是定义一个用于创建对象的接口,让子类决定具体实例化那一个类。具体到JavaScript中,因为根本就没有标准OO里面类的概念,开发人员发明了一种函数,用函数来封装以特定接口来创建对象的细节。
function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
return o;
}
var person1 = createPerson("Haha", 34, "Doctor");
var person2 = createPerson("Hehe", 23, "worker");
使用工厂模式创建对象解决了代码重复的问题,却没有解决对象识别的问题:所有由createPerson函数创建的对象都是Object构造函数的实例。为了解决这个问题,引入了构造函数模式。
三、构造函数模式
通过创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() {
alert(this.name);
};
}
var person1 = new Person("Haha", 34, "Doctor");
var person2 = new Person("Hehe", 23, "Worker");
此处,我们必须使用new操作符来调用构造函数Person()。这样就会有以下四个步骤:
1)创建一个新对象;
2)将新对象赋给构造函数的作用域(因此this就指向了这个新对象);
3)执行构造函数中的代码(为这个新对象添加属性);
4)返回新对象(没有明确return其他对象,默认返回新对象);
现在,person1和person2不仅仅都是Object构造函数的实例,而且都是Person构造函数的实例。构造函数模式的缺点是:每个构造函数中定义的方法在其生成的每个实例上都重新创建一遍,如果生成的实例比较多或者每个方法都比较大,这种模式会非常消耗资源。有一种变通方法如下:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {
alert(this.name);
}
var person1 = new Person("Haha", 34, "Doctor");
var person2 = new Person("Hehe", 23, "Worker");
通过把方法转移到构造函数外部,对象person1和person2实现了共享函数sayName()。带来的问题是sayName()函数处在全局作用域中,从而失去封装性问题和大量类似函数的数量膨胀问题。为此,我们想到了原型模式。
四、原型模式
我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型(指向这个对象的函数)的所有实例共享的属性和方法。注意:这个对象是在创建函数的同时,就已经自动被创建了,而且通过函数的prototype属性和对象的constructor属性进行了相互指向。在对函数调用了new操作符之后,所有生成的实例把函数的prototype属性指向的对象作为自己的原型对象。
function Person() {
}
Person.prototype.name = "Haha";
Person.prototype.age = 34;
Person.prototype.job = "Doctor";
Person.prototype.sayName = function() {
alert(this.name);
};
var person1 = new Person();
var person2 = new Person();
person1.sayName === person2.sayName;
各个对象之间的关系:

注意一:实例对象和构造函数没有直接的关联,它们只是在生成时,把自己的内部属性[[Prototype]]指向了Person Prototype对象,而和Person构造函数之间并没有之间联系起来。造成的影响是:当实例生成后去改变Person构造函数的prototype属性,使之重新指向一个对象的话,实例的[[Prototype]]属性不会跟随变化。
注意二:原型对象带来的对象属性的读和写的不对等性。
注意三:原型的动态性,本质是实例与原型之间的松散连接关系。
原型模式的问题是:1、没有了构造函数传递初始化参数这一环节;2、引用类型值的共享带来的问题。
五、组合使用构造函数模式与原型模式
因为构造函数模式和原型模式的优缺点互补性,创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性。
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("Haha", 34, "Doctor");
var person2 = new Person("Hehe", 23, "Worker");
到了这一步,JavaScript中创建对象的方法应该学习的差不多了,但是,总会有一些特殊需求。
六、动态原型模式
如果你对上面第五种方法中的组合模式感到困惑或者不爽,那么你可以试试这个动态原型模式。它把所有的信息都封装在构造函数中,而通过在构造函数中初始化原型(仅在必要的情况下),保存了组合模式的优点。
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
if (typeof this.sayName !== "function") {
Person.prototype.sayName = function() {
alert(this.name);
};
}
}
七、寄生构造函数模式
该模式的基本思想是:创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后在返回新创建的对象。
function Person(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
return o;
}
var friend = new Person("Haha", 34, "Doctor");
friend.sayName();
此处与工厂模式的区别仅仅是:使用new去调用构造函数。注意在构造函数中没有去使用默认生成的新对象this,并且通过显式的return语句改写了构造函数的默认返回对象。
这个模式可以在特殊的情况下用来为对象创建构造函数。
八、稳妥构造函数模式
JavaScript中的稳妥对象(durable objects),指的是没有公共属性,而且其方法也不引用this的对象。稳妥对象适合在一些安全的环境中(禁止this和new),或者防止数据被其他应用程序改动时使用。
function Person(name, age, job) {
var o = new Object();
// 可在此处定义室友变量和函数
// 添加方法
o.sayName = function() {
alert(name);
};
return o;
}
注意:此种模式创建的对象中,除了使用sayName()方法之外,没有其他办法访问name的值。
关于JavaScript中的创建对象的学习总结的更多相关文章
- JavaScript 中 关于 this 的学习笔记
今天上午主要学习了js中的 this ,因为之前学习面向对象时,this这个东西出现的还是很频繁的,理解的很不透彻,感觉老被JAVA的思想带进坑里,所以对它特别关注. 首先贴一个大神的一篇博客,我是通 ...
- JavaScript中关于创建对象的笔记
1,最基本的两种创建对象的方式:构造函数|| 字面量 构造函数: var person = new Object(); person.name = "chen1zee1"; per ...
- Javascript中回调函数的学习笔记
function a_b(kkis){ document.body.style.background ='red'; kkis(); } function fli(){ alert('######## ...
- 详解JavaScript中的Object对象
Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是 ...
- 全面理解Javascript中Promise
全面理解Javascript中Promise 最近在学习Promise的时候,在网上收集了一些资料,发现很多的知识点不够系统,所以小编特意为大家整理了一些自认为 比较好的文章,供大家更好地学习js中非 ...
- Javascript中的Object对象
Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是 ...
- 深入理解JavaScript中创建对象模式的演变(原型)
深入理解JavaScript中创建对象模式的演变(原型) 创建对象的模式多种多样,但是各种模式又有怎样的利弊呢?有没有一种最为完美的模式呢?下面我将就以下几个方面来分析创建对象的几种模式: Objec ...
- Javascript中String对象的的简单学习
第十一课String对象介绍1:属性 在javascript中可以用单引号,或者双引号括起来的一个字符当作 一个字符对象的实例,所以可以在某个字符串后再加上.去调用String 对象 ...
- Javascript学习1 - Javascript中的类型对象
原文:Javascript学习1 - Javascript中的类型对象 1.1关于Numbers对象. 常用的方法:number.toString() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...
随机推荐
- BZOJ4668: 冷战
并查集,按秩合并,树高log,暴力查询. 果然bzoj新挂的题中过的人多的全是sb题. 写了一发秒WA,发现姿势不对.(@_@) 然后过了50min,开始怀疑人生.(*_*) 这么长时间我lct都写完 ...
- 使用Navicat导入导出表的数据做测试(转载)
当我们对MySQL数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1 ...
- 《Struts2.x权威指南》学习笔记1
第2章 Struts的hello world 在介绍hello world项目前,文中要求下载和安装Struts2,主要是下载lib库和文档,可用于通过命令行进行代码编译.由于公司采用IntelliJ ...
- easyUI validatebox设置值和获取值,以及属性和方法
一:表单元素使用easyui时,textbox和validatebox设置值和获取值的方式不一样[转] 1.为text-box设置值只能使用id选择器选择表单元素,只能使用textbox(" ...
- RandomAccessFile类
File类只是针对文件本身进行操作,而如果要对文件内容进行操作,则可以使用RandomAccessFile类,此类属于随机读取类,可以随机地读取一个文件中指定位置的数据. //============ ...
- MySQL学习笔记——安装及配置环境
1.安装的版本为mysql-5.6.24-win32.1432006610压缩版 查看教程http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345b ...
- ie6下absolute:fixed问题,完美兼容
普通css代码 .fix_foot{height: 30px; background: #ff0000; position: %; z-index:;} ie6兼容代码 * html,* html b ...
- Ubuntu下如何安装YouCompleteMe插件
Ubuntu安装YouCompleteMe插件 简介: 众所周知, Vim是一款linux下的文本编辑器, 其最基础的工作就是编辑文本,而不管该文本的内容是什么. 在Vim被程序员所使用后,其慢慢的被 ...
- 【原】Gradle调用shell脚本和python脚本并传参
最近由于项目自动化构建的需要,研究了下gradle调用脚本并传参的用法,在此作个总结. Pre build.gradle中定义了$jenkinsJobName $jenkinsBuild两个Jenki ...
- asp.net mvc 在View中获取Url参数的值
如果url是 /home/index?id=3 直接Request就ok. 但是如果路由设定为:{controller}/{action}/{id} url是 /home/index/3 这时想在 ...