关于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() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...
随机推荐
- DNS(一)之禁用权威域名服务器递归解析
DNS dns是互联网中最核心的带层级的分布式系统,负责把域名解析成ip,把IP解析出域名,以及宣告邮件路由信息等等,使得使用域名访问网站,收发邮件成了可能. bind(berkeley Intern ...
- C#开发和调用Web Service
http://blog.csdn.net/h0322/article/details/4776819 1.1.Web Service基本概念 Web Service也叫XML Web Service ...
- NSXMLParser解析本地.xml数据(由于like7xiaoben写的太好了,我从她那里粘贴过来的)
NSXMLParser解析简要说明 .是sax方法解析 .需要创建NSXMLParser实例 (alloc) 并创建解析器 (initWithData:) 为解析器定义委托 (setDelegate: ...
- 简单说说Tk和Tcl
开园第一个博客,简单说说Tk和Tcl. 我接触Tk和Tcl是在学习Python Tkinter时候,创建Tk对象,下面言归正传: Tcl:工具命令语言,英文全称为Tool Command Langua ...
- wpf 窗体内容旋转效果 网摘
<Window x:Class="simplewpf.chuangtixuanzzhuan" xmlns="http://schemas.micros ...
- matlab解三元二次方程组
C1=7.0863; C2=6.8971; C3=0.4929; C4=0.8131; C5=1.8240; C6=3.8108; C7=3.7318; C8=-2.2238; C9=1.9905; ...
- bootstrap弹框
http://v3.bootcss.com/javascript/#modals 参考bootstrap官网 模态框做php后端 前端一直不行,但是很多时候 用到ajax都要用到弹框,一直在代码里面找 ...
- telnet连接ip
win7 telnet命令无法开启的解决方案(不是内部命令或外部命令) 出处:西西整理 作者:西西 日期:2012-12-21 14:22:06 [大 中 小] 评论: 0 | 我要发表看法 如果你想 ...
- asp.net+mysq 数据库操作类
对数据库操作的使用方法: 1.引入命名空间 2.操作.三四行代码即可完成数据操作.类似于: using System; using System.Data; using System.Text; us ...
- win10系统点击关机按钮后无法关机的解决办法
先吐槽下:我越发的发现我现在成了修电脑的了,我的职位是linux运维,现在干的活很蛋疼,公司只有我一个运维,修电脑.搞网络.抬服务器.弄监控,搭环境.搞自动化发布.弄虚拟化都我一个人哇.好了,打住. ...