javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法。这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作。接下来将为大家讲解在JS中面向对象的实现。
工厂模式
工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象。其实现方法非常简单,也就是在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可。
|
1
2
3
4
5
6
7
8
9
10
11
|
function createBlog(name, url) { var o = new Object(); o.name = name; o.url = url; o.sayUrl= function() { alert(this.url); } return o;} |
可以看到工厂模式的实现方法非常简单,解决了创建多个相似对象的问题,但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,因此出现了构造函数模式。
构造函数模式
ECMAScript中构造函数可以创建特定类型的对象,类似于Array、Date等原生JS的对象。其实现方法如下:
|
1
2
3
4
5
6
7
8
9
10
|
function Blog(name, url) { this.name = name; this.url = url; this.alertUrl = function() { alert(this.url); }}console.log(blog instanceof Blog); // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能 |
这个例子与工厂模式中除了函数名不同以外,细心的童鞋应该发现许多不同之处:
函数名首写字母为大写 (虽然标准没有严格规定首写字母为大写,但按照惯例,构造函数的首写字母用大写
没有显示的创建对象
直接将属性和方法赋值给了this对象
没有return语句
使用new创建对象
能够识别对象(这正是构造函数模式胜于工厂模式的地方)
构造函数虽然好用,但也并非没有缺点,使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面(也许有些童鞋已经看出缺点,嘘!)。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
function Blog(name, url) { this.name = name; this.url = url; this.alertUrl = alertUrl;}function alertUrl() { alert(this.url);}blog.alertUrl(); // http://sc.jb51.net/blog2.alertUrl(); // http://www.jb51.net/ |
我们将alertUrl设置成全局函数,这样一来blog与blog2访问的都是同一个函数,可是问题又来了,在全局作用域中定义了一个实际只想让Blog使用的函数,显示让全局作用域有些名副其实,更让人无法接受的是在全局作用域中定义了许多仅供特定对象使用的方法,浪费空间不说,显然失去了面向对象封装性了,因此可以通过原型来解决此问题。
原型模式
我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
function Blog() {}Blog.prototype.name = 'wuyuchang';Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];Blog.prototype.alertInfo = function() { alert(this.name + this.url + this.friend );}// 以下为测试代码var blog = new Blog(), blog2 = new Blog();blog.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4blog2.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4blog.name = 'wyc1';blog.friend.pop();blog2.name = 'wyc2';blog.alertInfo(); // wyc1http://***.comfr1,fr2,fr3blog2.alertInfo(); // wyc2http://+++.comfr1,fr2,fr3 |
原型模式也不是没有缺点,首先,它省略了构造函数传递初始化参数这一环节,结果所有实例在默认情况下都取得了相同的属性值,这样非常不方便,但这还是不是原型的最大问题,原型模式的最大问题在于共享的本性所导致的,由于共享,因此因此一个实例修改了引用,另一个也随之更改了引用。因此我们通常不单独使用原型,而是结合原型模式与构造函数模式。
混合模式(原型模式 + 构造函数模式)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
function Blog(name, url, friend) { this.name = name; this.url = url; this.friend = friend;}Blog.prototype.alertInfo = function() { alert(this.name + this.url + this.friend);}blog.friend.pop();blog.alertInfo(); // wuyuchanghttp://tools.jb51.net/fr1,fr2blog2.alertInfo(); // wychttp://**.coma,b |
混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。优点甚多。这种模式在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。
动态原型模式
动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断该方法是否有效而选择是否需要初始化原型。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function Blog(name, url) { this.name = name; this.url = url; if (typeof this.alertInfo != 'function') { // 这段代码只执行了一次 alert('exe time'); Blog.prototype.alertInfo = function() { alert(thia.name + this.url); } }} blog2 = new Blog('wyc', 'http:***.com'); |
可以看到上面的例子中只弹出一次窗,'exe time',即当blog初始化时,这样做blog2就不在需要初始化原型,对于使用这种模式创建对象,可以算是perfect了。
转载地址:http://www.jb51.net/article/53823.htm
javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)的更多相关文章
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂 ...
- javascript 面向对象编程(工厂模式、构造函数模式、原型模式)
javascript 面向对象编程(工厂模式.构造函数模式.原型模式) CreateTime--2018年3月29日17:09:38 Author:Marydon 一.工厂模式 /** * 工厂模 ...
- JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承
说好的讲解JavaScript继承,可是迟迟到现在讲解.废话不多说,直接进入正题. 既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考<面向对象J ...
- javascript 面向对象基础 (1)
常见的创建对象的方式有3种: ① 声明变量的方式 var obj1 = { key1: "val1", key1: "val2", show: function ...
- 了解JavaScript 面向对象基础 & 原型与对象
面向对象语言中的对象 老是能听到什么基于对象, 面向对象. 什么是对象, 如果有面向对象基础的人可以无视了, 下面举个简单的例子给大家讲讲面向对象中, 对象的定义, 这个是比较通用的, 不过对于JS来 ...
- JavaScript面向对象编程(二)构造函数和类
new关键字和构造函数 在文章JavaScript面向对象编程(一)原型与继承中讨论啦JavaScript中原型的概念,并且提到了new关键字和构造函数.利用new关键字构造对象的实例代码如下: // ...
- JavaScript面向对象基础与this指向问题
前 言 我们的程序语言经历了从"面向机器".到"面向过程".再到"面向对象"的一个过程.而JavaScript是一 ...
- Javascript对象基础讲解
1.Object对象详解 javascript 里最基本的数据类型是对象. avaScript里的对象其实是一个无序的属性集合,属性又是一个个的名-值对. 除了字符串,数字,true,false,nu ...
- Javascript面向对象编程(二)--- 构造函数的继承
这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个"动 ...
随机推荐
- php5.5 + apache2.4 安装配置
php5.5 做了大量的更新,在与apache搭配的时候如何选择也很有讲究,这里我们以64位 php5.6 和 Apache2.4为例介绍如何配置. 工具/原料 Win7/8 64位 php5.5.6 ...
- ThinkPHP - 进行继承时的 构造函数
被继承文件:PublicController.class.php <?php namespace Admin\Controller; use Think\Controller; class Pu ...
- jquery.zclip—复制剪贴板(兼容各大浏览器)
开始前说两句 WEB开发中,要让用户复制页面中的一段代码.URL地址等信息,为了避免用户拖动鼠标再进行右键复制操作而可能出现的差错,我们可以直接在页面中放置一个复制按钮,只需要轻轻一点这个复制按钮,内 ...
- U+00A0 (Non-breaking space)无法被正确压缩
Code Glyph Decimal HTML Description #U+00A0 Non-breaking space 0096 https://zh.wikipedia.org/wik ...
- redis(一)简介
啥也不说百度各种简介 推荐一个博客灰常详细的介绍 nosqlfan 接下来发布redis+USE_TCMALLOC 的安装配置,博客好多坑,找一篇好文真心难啊. redis+keepalived ...
- 浅谈HTML之模仿人人网登陆界面(新手必学)
为方便大家对web相关知识的了解,现谈谈新手如何从HTML css Javascript到以后后台的发展.首先,让大家看看HTML仿人人登陆界面: <!doctype html> < ...
- 微软新一代输入法框架 TSF - Text Service Framework 小小的研究
实际上windows中有两套输入法框架,一套叫做imm32.一套叫做tsf,win7以后的新系统都是优先使用tsf的,现在新出的输入法基本也是基于tsf的. 你可以参考一下这篇文章,虽然是c++的代码 ...
- C# 仿金山毒霸启动和关闭淡入淡出效果
原文 C# 仿金山毒霸启动和关闭淡入淡出效果 01 #region 窗体关闭效果 02 03 #region 私有方法 04 [DllImportAttribute("user32.dl ...
- C# MVC 自学笔记—5 添加模型
==============================翻译============================== 在本节中,您将添加一些类来管理数据库中的电影.这些类将 ASP.NET M ...
- 使用CDN对动态网站内容加速有效果吗
个资源文件,有利于减少原始服务器的压力. 缓存网页内容 对于动态网站而言,部分访问量大的网页内容可能改观不大,好比论坛的首页,置顶的帖子很少泛起大转变,因此这样的网页可 ...