js面向对象的程序设计 --- 中篇(创建对象) 之 工厂模式和 构造函数模式
创建对象
虽然Object构造函数或对象字面量都可以用来创建单个对象,但这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量重复代码。 ·工厂模式
工厂模式是一种广为人知的设计模式,这种模式抽象了创建对象的具体过程。考虑到ECMAScript中无法创建类,开发人员就发明了一种函数,用函数来封装
以特定接口创建对象的细节 // code...
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 person = createPerson("tom",25,"coder");
console.log(person); //{name: "tom", age: 25, job: "coder", sayName: ƒ}
工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别的问题(即怎样知道一个对象的类型),随着js的发展,又一个新的模式出现了 ·构造函数模式
ECMAScript 中的构造函数可以用来创建特定类型的对象。像Object,Array这样的原生构造函数,在运行时会自动出现在执行环境中。此外也可以
创建自定义的构造函数,从而创建自定义类型的属性和方法
// code ..
function Person(name , age , job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function () {
console.log(this.name);
}
}
var person_a = new Person('lee',33,'doctor');
console.log(person_a); //Person {name: "lee", age: 33, job: "doctor", sayName: ƒ}
var person_b = new Person('wang',22,'model');
// 这两个对象都有一个 constructor (构造函数)属性,都指向Person
console.log(person_a.constructor == Person); // true
// 对象的constructor属性最初是来标识对象类型的。但是提到检测对象类型,还是instanceof操作符更可靠一些
console.log(person_a instanceof Person); // true
console.log(person_a instanceof Object); // true
// 可以得出,我们在这个例子中创建的所有对象既是Object的实例也是Person的实例
// 创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;这正是构造函数模式胜过工厂模式的地方。在
//这个例子中,person_a和person_b之所以同时是Object的实例,是因为所有对象均继承自Object。 console.log(person_a.sayName == person_b.sayName); // false
这种方式调用构造函数实际上会经历4个步骤:
1,创建一个新对象
2,将构造函数的作用域给新对象(因此this就指向了这个对象)
3,执行构造函数中的代码(为这个对象添加属性)
4,返回新对象 构造函数的缺点:
每个方法都要在每个实例上重新创建一遍,在前面的例子中,person_a和person_b都有一个名为sayName()方法,但两个方法不是同一个Function实例
。不要忘记--- ECMAScript中的函数是对象,因此每定义一个函数,也就是实例化了一个对象。
显然:创建两个完成同样任务的Function实例的确没有必要;况且有this对象在,根本不用在执行代码前就把函数绑定到特定对象上面。
因此,大可向下面这样,通过把函数定义到构造函数外部来解决这个问题
// code..
function Cat(){
this.cry = miao;
}
function miao(){
console.log("miao~~");
}
var cat = new Cat();
cat.cry(); // miao~~
由于this.cry指针指向了外部的miao()函数,那么,所有由Cat构造函数创建的对象就共享了在全局作用域中定义的同一个miao()函数。这样做确实解决了
两个函数做同一件事的问题。可以新问题又来了:在全局作用域中定义的函数实际上只能被某个对象调用,这让全局作用域有点名不其实;
更让人无法接受的是:如果对象需要定义很多方法,那么就要定义很多个全局函数,于是我们这个自定义的引用类型就丝毫没有封装性可言了。
好在,这个问题可以通过原型模式解决
js面向对象的程序设计 --- 中篇(创建对象) 之 工厂模式和 构造函数模式的更多相关文章
- js面向对象的程序设计 --- 中篇(创建对象) 之 原型模式
·原型模式 我们创建的每一个函数都由一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有 实例共享的属性和方法. 如果按照字面意思来理解,那 ...
- 重学js之JavaScript 面向对象的程序设计(创建对象)
注意: 本文章为 <重学js之JavaScript高级程序设计>系列第五章[JavaScript引用类型]. 关于<重学js之JavaScript高级程序设计>是重新回顾js基 ...
- js面向对象、创建对象的工厂模式、构造函数模式、原型链模式
JS面向对象编程(转载) 什么是面向对象编程(OOP)?用对象的思想去写代码,就是面向对象编程. 面向对象编程的特点 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有对象上继承出新的对象 ...
- JS面向对象的程序设计
面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装.继承.多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义J ...
- 面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式
什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下 ...
- JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
什么是面向对象?面向对象是一种思想. 面向对象可以把程序中的关键模块都视为对象, 而模块拥有属性及方法. 这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂 ...
- JavaScript面向对象OOM 2(JavaScript 创建对象的工厂模式和构造函数模式)
在创建对象的时候,使用对象字面量和 new Object() 构造函数的方式创建一个对象是最简单最方便的方式.但是凡是处于初级阶段的事物都会不可避免的存在一个问题,没有普适性,意思就是说我要为世界 ...
- javascript面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模式)
面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现. 工厂 ...
- javascript 面向对象编程(工厂模式、构造函数模式、原型模式)
javascript 面向对象编程(工厂模式.构造函数模式.原型模式) CreateTime--2018年3月29日17:09:38 Author:Marydon 一.工厂模式 /** * 工厂模 ...
随机推荐
- 安装Gitlab到Ubuntu(APT)
运行环境 系统版本:Ubuntu 16.04.6 LTS 软件版本:Gitlab-ce-11.10.1 硬件要求:最低2核4GB,建议4核8GB 安装过程 1.安装依赖 root@localhost: ...
- 转:Laravel 项目开发规范
文件介绍很好 值得细细看看 https://www.jianshu.com/p/e464a35e5ed2 https://learnku.com/docs/laravel-specification/ ...
- SVN提交更新文件,抛出"svn: No such revision 27106"异常问题处理
SVN,不管是更新或者是提交原来存在的文件,都会抛出此异常"svn: No such revision 27106",注意,是原来存在的文件,要是新增的文件,不会出现此问题. 百度 ...
- js参数自定义
function test(){ //利用对象自定义参数名称 var t = {P1:"a",P2:"b"} //返回的数据 var ttt = {a:&quo ...
- 提取 Microsoft.ReportViewer等dll
ReportViewer 在开发环境没问题 发布以后可能会提示找不到 Microsoft.ReportViewer 下的几个dll 可以用用下面脚本在开发服务器上提取 相应的dll @SET dest ...
- Redis基础详解
1. Redis是什么.特点.优势 Redis是一个开源的使用C语言编写.开源.支持网络.可基于内存亦可持久化的日志型.高性能的Key-Value数据库,并提供多种语言的API. 它通常被称为 数据结 ...
- Linux C++ 单链表添加,删除,输出,逆序操作
/*单链表操作*/#include <iostream>using namespace std; class Node{ public: Node(){ next=0; } Node(in ...
- mysql 视图、触发器、事务、存储过程、函数
一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- C++-蓝桥杯-矩阵乘法[快速幂]
忘了改矩阵的大小居然还有33分,我醉了 #include <cstdio> ; struct Matrix{int a[N][N];}; int n,m; Matrix A,O,I; Ma ...
- SVN之TortoiseSVN使用02
TortoiseSVN常用操作和安装eclipse的svn插件 一.关于TortoiseSVN的介绍 1. 安装TortoiseSVN图像化操作软件,便于操作SVN! 如图有两种版本的,一个是32位, ...