面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式
什么是面向对象?面向对象是一种思想!(废话)。
面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法。这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作。接下来将为大家讲解在JS中面向对象的实现。
工厂模式
工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象。其实现方法非常简单,也就是在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可。
function createBlog(name, url) {
var o = new Object();
o.name = name;
o.url = url;
o.sayUrl= function() {
alert(this.url);
}
return o;
} var blog1 = createBlog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/');
可以看到工厂模式的实现方法非常简单,解决了创建多个相似对象的问题,但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,因此出现了构造函数模式。
构造函数模式
ECMAScript中构造函数可以创建特定类型的对象,类似于Array、Date等原生JS的对象。其实现方法如下:
function Blog(name, url) {
this.name = name;
this.url = url;
this.alertUrl = function() {
alert(this.url);
}
} var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/');
console.log(blog instanceof Blog); // true, 判断blog是否是Blog的实例,即解决了工厂模式中不能
这个例子与工厂模式中除了函数名不同以外,细心的童鞋应该发现许多不同之处:
- 函数名首写字母为大写 (虽然标准没有严格规定首写字母为大写,但按照惯例,构造函数的首写字母用大写
- 没有显示的创建对象
- 直接将属性和方法赋值给了this对象
- 没有return语句
- 使用new创建对象
- 能够识别对象(这正是构造函数模式胜于工厂模式的地方)
构造函数虽然好用,但也并非没有缺点,使用构造函数的最大的问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的),然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面(也许有些童鞋已经看出缺点,嘘!)。
function Blog(name, url) {
this.name = name;
this.url = url;
this.alertUrl = alertUrl;
} function alertUrl() {
alert(this.url);
} var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/'),
blog2 = new Blog('cnblogs', 'http://www.cnblogs.com/');
blog.alertUrl(); // http://www.cnblogs.com/wuyuchang/
blog2.alertUrl(); // http://www.cnblogs.com/
我们将alertUrl设置成全局函数,这样一来blog与blog2访问的都是同一个函数,可是问题又来了,在全局作用域中定义了一个实际只想让Blog使用的函数,显示让全局作用域有些名副其实,更让人无法接受的是在全局作用域中定义了许多仅供特定对象使用的方法,浪费空间不说,显然失去了面向对象封装性了,因此可以通过原型来解决此问题。
原型模式
我们创建的每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性及方法。
function Blog() {
} Blog.prototype.name = 'wuyuchang';
Blog.prototype.url = 'http://www.cnblogs.com/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://www.cnblogs.com/wuyuchang/fr1,fr2,fr3,fr4
blog2.alertInfo(); // wuyuchanghttp://www.cnblogs.com/wuyuchang/fr1,fr2,fr3,fr4 blog.name = 'wyc1';
blog.url = 'http://***.com';
blog.friend.pop();
blog2.name = 'wyc2';
blog2.url = 'http://+++.com';
blog.alertInfo(); // wyc1http://***.comfr1,fr2,fr3
blog2.alertInfo(); // wyc2http://+++.comfr1,fr2,fr3
原型模式也不是没有缺点,首先,它省略了构造函数传递初始化参数这一环节,结果所有实例在默认情况下都取得了相同的属性值,这样非常不方便,但这还是不是原型的最大问题,原型模式的最大问题在于共享的本性所导致的,由于共享,因此因此一个实例修改了引用,另一个也随之更改了引用。因此我们通常不单独使用原型,而是结合原型模式与构造函数模式。
混合模式(原型模式 + 构造函数模式)
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);
} var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang/', ['fr1', 'fr2', 'fr3']),
blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']); blog.friend.pop();
blog.alertInfo(); // wuyuchanghttp://www.cnblogs.com/wuyuchang/fr1,fr2
blog2.alertInfo(); // wychttp://**.coma,b
混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性。每个实例都会有自己的一份实例属性,但同时又共享着方法,最大限度的节省了内存。另外这种模式还支持传递初始参数。优点甚多。这种模式在ECMAScript中是使用最广泛、认同度最高的一种创建自定义对象的方法。
动态原型模式
动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型(仅第一个对象实例化时初始化原型),这个可以通过判断该方法是否有效而选择是否需要初始化原型。
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);
}
}
} var blog = new Blog('wuyuchang', 'http://www.cnblogs.com/wuyuchang'),
blog2 = new Blog('wyc', 'http:***.com');
可以看到上面的例子中只弹出一次窗,'exe time',即当blog初始化时,这样做blog2就不在需要初始化原型,对于使用这种模式创建对象,可以算是perfect了。
此博文参考《JavaScript高级程序设计》第3版,但语言都经过简化,例子也重写过,如果有什么不懂的地方请留言回复,作者将更新博客。
面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式的更多相关文章
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂 ...
- javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现. 工厂 ...
- 面向对象JS基础
什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下 ...
- js基础知识温习:构造函数与原型
构造函数 构造函数主要用于初始化新对象.按照惯例,构造函数名第一个字母都要大写. 构造函数有别于其它函数在于它使用new操作符来调用生成一个实例对象.换句话说,如果一个函数使用new操作符来调用,则将 ...
- c++面向对象 之 基础 类修饰符 构造函数 友元函数
1,类和对象 定义一个类,本质上是定义一个数据类型的蓝图.这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作. 类定义格式 ...
- JavaScript继承基础讲解,原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承
说好的讲解JavaScript继承,可是迟迟到现在讲解.废话不多说,直接进入正题. 既然你想了解继承,证明你对JavaScript面向对象已经有一定的了解,如还有什么不理解的可以参考<面向对象J ...
- 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)
一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...
- JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式
1.单例模式 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- JavaScript之面向对象学习七(动态原型模式、寄生构造函数模式、稳妥构造函数模式创建自定义类型)
一.动态原型模式 在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此! 有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可 ...
随机推荐
- LightOJ 1205 Palindromic Numbers
数位DP.... Palindromic Numbers Time Limit: 2000MS Memory Limit: 32768KB 64bit IO Format: %lld & %l ...
- MVC简单的认识
学习一个新知识,首先要了解的就是以下几个问题,它是什么?它能干什么?使用它有什么优点?这篇文章就环绕这几个问题来展开讨论. mvc不是一种编程语言,严格来说.它都不算是一门技术.它是开发软件时使用的一 ...
- Team Foundation Server 2015使用教程--权限为读取器的团队成员连接tfs及checkin操作
- [Network]Transport Layer
1 Principles behind Transport Layer Services 1.1 Multiplexing/Demultiplexing Multiplexing at sender ...
- 阿里巴巴2014研发project师实习生面试经历
java研发project师的初面是在上周三进行的,终于结果到了晚上才出,而没有通过的则是一结束网上就更新了状态.之后阿里通知这周三,也就是今天进行二面. 凑巧的是今早被舍友吵醒,中午那个困啊,但没时 ...
- .Net反编译实战
原文:.Net反编译实战 当你面对一个已经部署好的网站,功能,性能都非常不给力的时候,你会怎么办? 当你尝试去了解这个网站业务逻辑,代码逻辑和数据库逻辑时却发现根本没有任何资料时你会怎么办? 当你准备 ...
- 移动web点5像素的秘密(转)
最近和一个朋友聊天,朋友吐露了工作上的一些不开心,说自己总是喜欢跟别人比较,活得比较累,这种感觉大部分人经历过,往往觉得是自己心态不好,其实不然,这是人性,此时应该快速摆脱这种状态,想到DOTA大9神 ...
- 华夏互联与逐浪CMS旗下三款软件获著作权登记
北京时间2014年7月24日消息: 上海逐一软件科技公司长下三款软件通过中国知识产权局登记,当中包含全新的CMS2 x2.0主产品.移动门户管理系统.云台管理系统. 除主产品CMS2 x2.0( ...
- High Performance Browser Networking - TCP UDP TLS
延迟 定义和标准延迟 延迟简单地说,它是一种转移或信息包从起点到终点,所花费的时间. 延迟=发送延迟+传播延迟+处理延迟+排队延迟: Propagation delay 传播时延 传播时延这个概念.是 ...
- Testin一日游实验室发布的行级APP质量报告:在那里拍携程双赢
Testin实验室公布国庆出行旅途类APP质量报告:携程力压去哪儿夺冠 2014/09/28 · Testin · 实验室报告 一年一度的十一黄金周即将临近,旅游软件成为每外出行人手机必装软件.为此全 ...