什么是面向对象?面向对象是一种思想.

面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.
 
工厂模式
工厂模式是软件工程领域中一种广为人知的设计模式,由于ECMAScript无法创建类, 因此用函数封装以特定的接口创建对象.其实现方法非常简单,也就是在函数内创建一个对象,在给对象赋予属性及方法再将对象返回即可.
 /**
* 工厂模式
* 优点:解决了创造对象的问题
* 缺点:没有解决对象的识别问题 instanceof -> Object
* */
function createPerson(name, age, job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
};
return o;
} var person1 = createPerson("xialiu", 24, "shijiazhuang");
var person2 = createPerson("xiaobei", 22, "hainan");
console.log(person1);
console.log(person2);
可以看到工厂模式的实现方法非常简单,解决了创建多个相似对象的问题.但是工程模式缺无从识别对象的类型,因为全部都是Object, 不像Date, Array等,因此出现了构造函数模式.
构造函数模式
ECMAScript中构造函数可以创建特定类型的对象, 类似于Array, Date等原生JS的对象.其实现方法如下:
 /**
* 构造函数模式
* 优点:解决对象识别的问题
* 缺点:不同实例上的同名函数是不相等的.有this对象在,没有必要再执行代码前把函数绑定到特定对象上来.
* */
function Blog(name,url){
this.name = name;
this.url =url;
this.alerturl = function () {
console.log(alerturl);
}
}
var blog = new Blog("xiaomeng","HTTP://www.baidu.com/");
console.log(blog instanceof Blog);//true, 判断blog是否是Blog的实例,即解决了工厂模式中不能
console.log(blog);
这个例子和工厂模式中除了函数名不同以外,细心的同学应该发现许多不同之处.
函数名手写字母大写---虽然标准没有严格规定手写字母大写,但按照惯例,构造函数的首写字母用大写.
没有先时创建对象
直接将属性和方法赋给this对象
没有return语句
使用new创建对象
能够识别对象, 这是构造函数模式胜于工厂模式的地方
构造函数虽然好用,但也并非没有缺点,使用构造函数的最大问题在于每次创建实例的时候都要重新创建一次方法(理论上每次创建对象的时候对象的属性均不同,而对象的方法是相同的), 然而创建两次完全相同的方法是没有必要的,因此,我们可以将函数移到对象外面.
 function Blog(name, url) {
this.name = name;
this.url = url;
this.alertUrl = alertUrl;
}
function alertUrl() {
console.log(this.url);
}
var blog = new Blog("xiaokeai","http://www.xiaokeai.com/"), blog2 = new Blog("xiaomeinv","http://www.123.com/");
blog.alertUrl();
blog2.alertUrl();
我们将alertUrl设置成全局函数,这样一来blog和blog2访问的都是同一个函数了,可是问题又来了,在全局作用域中定义一个实际只想让blog使用的函数,显示让全局作用域有些名副其实,更让人无法接受的是在全局作用域中定义了许多仅供特定对象使用的方法,浪费空间不说,显然失去了面向对象的封装性了,因此可以通过原型来解决这个问题.
原型模式
我们创建的每个函数都有prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法.使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法.
 /**
* 原型模式
* */
function Blog(){
Blog.prototype.name = "xiaomeiren";
Blog.prototype.url = "http://www.xiaomeiren.com/";
Blog.prototype.friend = ["aaa", "bbb", "ccc", "ddd", "eee"];
Blog.prototype.alertInfo = function () {
console.log(this.name + ' ' + this.url + ' ' + this.friend);
}
}
var blog = new Blog(), blog2 = new Blog();
blog.alertInfo(); //"xiaomeiren http://www.xiaomeiren.com/ aaa,bbb,ccc,ddd,eee"
blog2.alertInfo(); //"xiaomeiren http://www.xiaomeiren.com/ aaa,bbb,ccc,ddd,eee" blog.name = "xiaomeiyun";
blog.url = "http://www.xiaomeiyun.com/";
blog.friend.pop(); blog2.name = "xiaomeiyun2";
blog2.url = "http://www.xiaomeiyun2.com/"; blog.alertInfo(); //"xiaomeiyun http://www.xiaomeiyun.com/ aaa,bbb,ccc,ddd"
blog2.alertInfo(); //"xiaomeiyun2 http://www.xiaomeiyun2.com/ aaa,bbb,ccc,ddd"
原型模式也不是没有缺点,首先,它忽略了构造函数传递初始化参数这一环节,结果所有实例在默认情况下都取得了相同的属性值,这样非常不方便,但这还不是原型的最大问题.原型模式最大问题在于共享的本性所导致的,由于共享,因此一个实例修改了引用,另一个也随之修改了引用.因此我们通常不单独使用原型,而是结合原型模式和构造函数模式.
混合模式
混合模式是原型模式加上构造函数模式
 /**
* 混合模式 = 原型模式 + 构造函数模式
* */
function Blog(name, url, friend ) {
this.name = name;
this.url = url;
this.friend = friend;
} Blog.prototype.alertInfo = function () {
console.log('名字:'+this.name + ' 博客:' + this.url + ' 好友:' + this.friend);
} var blog = new Blog("LiMing","http://www.limingweb.com/",["aaa", "bbb","ccc", "ddd"]),
blog2 = new Blog("LiMingming","http://www.limingmingweb.com/",["aaa", "bbb","ccc", "ddd"]);
blog.friend.pop();//arrayObject.pop();方法用于删除并返回数组的最后一个元素,并且数组长度减1.
blog.alertInfo();//名字:LiMing 博客:http://www.limingweb.com/ 好友:aaa,bbb,ccc
blog2.alertInfo();//名字:LiMingming 博客:http://www.limingmingweb.com/ 好友:aaa,bbb,ccc,ddd
混合模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享属性. 每个实例都会有自己的一份实例属性,但同时又共享这方法,最大限度的节省了内存.另外这种模式还支持传递初始数据.优点胜多,这种模式使用广泛,认同度最高的一种创建自定义对象的方法.
动态原型模式
动态原型模式将所有信息封装在了构造函数中,而通过构造函数中初始化原型,这个可以通过判断该方法是否有效而选择是否需要初始化原型.
 function Blog(name, url) {
this.name = name;
this.url = url;
if(typeof this.alertInfo != "function"){
//这段代码只执行一次
console.log("haha");
Blog.prototype.alertInfo = function () {
console.log('名字:'+this.name + ' 博客:' + this.url);
}
}
}
var blog = new Blog("LiMing","http://www.limingweb.com/"),
blog2 = new Blog("LiMingming","http://www.limingmingweb.com/");
运行效果;haha
即当blog初始化时,这样做blog2就不再需要初始化原型,对于这种模式创建对象,已经是很完美了.

JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)的更多相关文章

  1. javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)

    面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现.   工厂 ...

  2. JavaScript基础精华02(函数声明,arguments对象,匿名函数,JS面向对象基础)

    函数声明 JavaScript中声明函数的方式:(无需声明返回值类型) function add(i1, i2) {             return i1 + i2;//如果不写return返回 ...

  3. js面向对象小结(工厂模式,构造函数,原型方法,继承)

    最近过了一遍尼古拉斯泽卡斯的高级程序设计第三版(红皮书)第六章:面向对象程序设计,现在把总结出来的东西和大家分享一下. 主要内容如下: 1.工厂模式 2.构造函数模式 3.原型模式 4.继承 一.工厂 ...

  4. 第十四节 JS面向对象基础

    什么是面向对象:在不需要知道它内部结构和原理的情况下,能够有效的使用它,比如,电视.洗衣机等也可以被定义为对象 什么是对象:在Java中对象就是“类的实体化”,在JavaScript中基本相同:对象是 ...

  5. js面向对象编程(二)构造函数的继承(转载)

    Javascript面向对象编程(二):构造函数的继承 这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继 ...

  6. [Js]面向对象基础

    一.什么是对象 对象是一个整体,对对外提供一些操作 二.什么是面向对象 使用对象时,只关注对象提供的功能,不关注其内部细节,比如Jquery 三.Js中面向对象的特点 1.抽象:抓住核心问题 2.封装 ...

  7. JS面向对象基础

    以往写代码仅仅是为了实现特定的功能,后期维护或别人重用的时候,困难很大. Javascript作为完全面向对象的语言,要写出最优的代码,需要理解对象是如何工作的. 1.       对象是javasc ...

  8. js面向对象基础总结

     js中如何定义一个类? 定义的function就是一个构造方法也就是说是定义了一个类:用这个方法可以new新对象出来. function Person(name, age){ this.name = ...

  9. JS面向对象基础2

    根据之前看了面向对象相关的视频,按照自己的理解,整理出相关的笔记,以便自己的深入理解. javascript面向对象: 突发奇想,注意:===全等:是指既比较值,也比较类型(题外话,可忽略) 逻辑运算 ...

随机推荐

  1. MySQL入门第三天(下)——存储过程与存储引擎

    一.存储过程 1.简介 原始的SQL执行的流程: 通过存储过程,便可以简化以上流程,那么存储过程是什么,如何进行性能提高呢? 是什么? 存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和 ...

  2. 深入解析UUID及其应用(转载)

    UUID 编辑 UUID含义是通用唯一识别码 (Universally Unique Identifier),这 是一个软件建构的标准,也是被开源软件基金会 (Open Software Founda ...

  3. mysql中的直方图采样逻辑

    int handler::sample_next(uchar *buf) { // Temporary set inited to RND, since we are calling rnd_next ...

  4. 40套PSD欧美扁平化网页模板,可二次编辑开发,精品

    40套PSD欧美扁平化网页模板,可二次编辑开发,绝对精品,下载地址:百度网盘, https://pan.baidu.com/s/1uMF4MM_3UC2Q6mbyNomLfQ 模板内容预览:   小

  5. html简约风用户登录界面网页制作html5-css-jquary-学习模版

    2018--12-12 喜迎双十二,咳咳,,,,我不是打广告哈,购物的节日也不要忘记学习. 大家好,我又来了. 今天抽出来空把自己的学习心得给大家分享,这是一个可开发可扩展的用户登录界面,用于开发学习 ...

  6. JAVA基础学习之路(六)数组与方法参数的传递

    通常,向方法中传递的都是基本数据类型,而向方法中传递数组时,就需要考虑内存的分配 public class test2 { public static void main(String args[]) ...

  7. 【转】网游服务器中的GUID(唯一标识码)实现-基于snowflake算法

    本文中的算法采用twitter的snowflake算法,具体请搜索介绍,原来是用Scala写的,因我项目需要,改写成C++语言,主要用于高效的生成唯一的ID, 核心算法就是毫秒级时间(41位)+机器I ...

  8. 变量不加 var 声明——掉进坑中,无法自拔!

    整整一下午,都在解决 window.onresize 中方法丢失不执行的问题!姿势固定在电脑前,颈椎病都犯了. 前些日子与大家分享了一下关于 防止jquery $(window).resize()多次 ...

  9. tomcat下载、安装

    下载 官网地址:https://tomcat.apache.org/download-80.cgi 安装 直接安装即可.安装完毕后Tomcat的目录结构如下: bin:脚本目录 ​ 启动脚本:star ...

  10. struts2 result type属性说明

    首先看一下在struts-default.xml中对于result-type的定义: <result-types><result-type name="chain" ...