关于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() 不用具体介绍,把数字转换为字符串,相应的还有一个 ...
随机推荐
- photoshop切图介绍
第一部分:界面设置 1.点击“文件-新建”(或者ctrl+n)打开一个新建对话框.名称可随意填写.“预设”设置为自定,“宽度”一般选择1920,“单位”选为像素.“高度”可选择为2000,“单位”选为 ...
- python 培训之HTTP
1. urllib #!/usr/env/python # -*- coding:UTF-8 -*- from __future__ import print_function import sys ...
- python学习笔记-(一)初识python
1.python的前世今生 想要充分的了解一个人,无外乎首先充分了解他的过去和现在:咱们学习语言也是一样的套路 1.1 python的历史 Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈp ...
- 如何以nobody用户执行命令?
最近在logstash中使用nobody用户启动logstash,一想,nobody用户的shell不是/sbin/nologin吗? 不能登录执行命令呀? 于是看了一下它的启动脚本,是使用其他方式进 ...
- select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET
http://hi.baidu.com/%B1%D5%C4%BF%B3%C9%B7%F0/blog/item/e7284ef16bcec3c70a46e05e.html select函数用于在非阻塞中 ...
- linux安装pip
1.先说一下什么是pippip 是"A tool for installing and managing Python packages.",也就是说pip是python的软件安装 ...
- PHP中“简单工厂模式”实例讲解
原创文章,转载请注明出处:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 简单工厂模式:①抽象基类:类中定义抽象一些方法, ...
- angularjs笔记(二)
AngularJS API 4.AngularJS过滤器 使用一个管道符(|)添加到表达式和指令中 例1.格式化字母转为大写 <!DOCTYPE html> <html> &l ...
- 9月5日网页基础知识 通用标签、属性(body属性、路径、格式控制) 通用标签(有序列表、无序列表、常用标签)(补)
网页基础知识 一.HTML语言 HTML语言翻译汉语为超文本标记语言. 二.网页的分类 1.静态页面:在静态页面中修改网页内容实际上就是修改网页原代码,不能从后台操作,数据来只能来源于原于代码.静态网 ...
- JavaWeb学习笔记——Tomcat数据源
server.xml配置数据帐号和密码等