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 一.工厂模式 /** * 工厂模 ...
随机推荐
- ArcMap 发布地图服务,提示发布工具没有启动
Error: The server is not ready for publishing. Please check if the Publishing Tools on the server ar ...
- Java-公约公倍
题目: 如果两个数很大,怎样求最大公约数,最小公倍数?如果是n个数呢?比如1000个数的最小公倍数 分析:求a和b的最大公约数——辗转相除法(又叫欧几里得定理).即找到一个数,能对a,b都除尽.对于这 ...
- 轻量级RPC设计与实现第二版
在上一个版本中利用netty实现了简单的一对一的RPC,需要手动设置服务地址,限制性较大. 在本文中,利用zookeeper作为服务注册中心,在服务端启动时将本地的服务信息注册到zookeeper中, ...
- [JAVA] 面向对象小小总结
面向对象概述 符合人类思维习惯的编程思想 , 生活中存在着不同形态的事物 , 这些事物存在着不同的联系 , 在程序中使用对象来映射现实中事物 , 使用对象关系来描述事物之间的联系, 这种思想就是面向对 ...
- mac anyconnect 卸载方法
打开终端: 输入下面的命令 sudo /opt/cisco/vpn/bin/vpn_uninstall.sh 有问题 端口占用 sudo /opt/cisco/anyconnect/bin/webse ...
- xctf进阶-unserialize3反序列化
一道反序列化题: 打开后给出了一个php类,我们可以控制code值: `unserialize()` 会检查是否存在一个 `__wakeup()` 方法.如果存在,则会先调用 `__wakeup` 方 ...
- 2.Docker Compose 部署应用程序
部署 Tomcat version: '3.1' services: tomcat: restart: always image: tomcat container_name: tomc ...
- DFS/BFS-A - Red and Black
A - Red and Black There is a rectangular room, covered with square tiles. Each tile is colored eithe ...
- Pascal运行错误表
(A)DOS错误代码 1:错误的功能代码尝试错误的操作系统调用.2:文件未找到程序试图删除.重命名和打开一个不存在的文件.3:目录未发现目录不存在或是错误,也有可能是访问一个不存在的文件.4:打开太多 ...
- laravel中redis数据库的简单使用
1.简介 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s . 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Set ...