javascript--面向对象(二、工厂模式,构造函数,原型模式)

一、前言

上一篇介绍了对象的基本简单的概念和对象的数据属性和访问器属性,以及对这两种属性类型的一些操作,接来说一下与创建对象的模式。

二、创建对象的方式

(1)工厂模式

这种模式就是通过创建一个Object对象,并将属性和方法保存在Object对象中,将Object对象返回。

function createPerson(name, age, job){
            var obj = new Object();//通过创建Object来保存传递进来的属性
            obj.name = name;
            obj.age = age;
            obj.job = job;
            obj.sayName = function(){
                console.log(this.name);
            }
            return obj;//返回创建对象
        }

        var person1 = createPerson(‘jiang‘, 12, ‘software‘);
        person1.sayName();

在上面的例子中,声明一个createPerson()的函数,这个函数接受三个参数,而在函数体中实例化一个Object对象,来接收传递进来的参数,最后将创建的对象返回,这样子就能获得一个person对象。这种模式是一种广为人知的设计者模式,抽象了创建具体对象的过程。这种模式虽然解决了创建多个相似对象的问题,但是并没有结局对象识别的问题。而接下来的构造函数就解决了这样的问题

(二)构造函数模式

在大多数的面向对象编程,构造函数主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new一起使用在创建对象的语句中。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载(在javascript中并没有重载这个概念)。构造函数模式解决了对象识别的问题,它可以用来创建特定类型的对象。

function Person(name, age, job){
  this.name = name;
  this.age = age;
  this.job = job;
  this.sayName = function(){
  console.log(this.name);
  }
}

这种方式与工厂模式相比

  1.没有显示的创建对象
  2.直接将属性和方法赋给了this对象
  3.没有return语句

var person = new Person(‘jiang‘, 13, ‘sfs‘);
person.sayName(); 

通过new操作符创建实例,需要经历一下的步骤
   -> 创建一个新对象
   -> 将构造函数的作用域赋给了新对象,(因此this也就指向了新对象)
   -> 执行构造函数中的代码(为该新对象添加属性)
  -> 返回新对象

在两个不同的实例,虽然是两个不同的实例,但这两个对象都有一个constructor属性指向Person,所以也可以看出,构造函数模式对于工厂模式在于对象识别的区别

var person2 = new Person(‘zhen‘, 13, ‘sfs‘);
person2.sayName();
console.log(person.constructor == Person);//true
console.log(person2.constructor == Person);//true

所谓构造函数模式,其实也是函数。跟其他函数的区别就在于调用的方式,任何函数通过new操作符来调用的,就是构造函数,如果不是通过new操作符调用的就是普通的函数。

当然构造函数并不是完美的,其问题就在于,每个方法都要在实例上重新创建一次,也就是说两个实例的方法是不相等的。这样使得有些多余。占用内存。

  function Person(name, age, job){
			this.name = name;
			this.age = age;
			this.job = job;
			this.sayName = sayName;
		}
		function sayName(){
			console.log(this.name);
		}

将对象内的方法提取到构造函数外面,可以减少同一方法的重复定义。但是这种方式也不好,于是出现了一下的原型模式

(三)原型模式

prototype 每个函数都有的属性,是指向一个对象的指针,包含了可以有特定类型的所有实例共享的属性和方法,换句话说,prototype就是通过调用函数而创建的对象实例的原型对象,其好处就是可以让所有对象实例共享包含的属性和方法。

 function Person(){}

		Person.prototype.name = ‘jiang‘;
		Person.prototype.age = 15;
		Person.prototype.job = ‘sf‘;
		Person.prototype.sayName = function(){
			console.log(this.name);
	        };
		var person = new Person();
		person.sayName();         

首先声明一个空的函数。将对象的方法和属性都放到prototype属性上。这样使用构造函数的方式创建新对象,新对象也会拥有相同的属性和方法。那么有人就会问了,Person函数中分明是空的,那么为何创建出来的新对象会有这些属性和方法呢?那么首先就要了解一下什么是原型对象。

(a)原型对象

当我们创建一个新的函数的同时,与之同时prototype会作为新函数的属性被创建出来,而这个属性呢就是一个指针,会指向新函数的原型对象。而在默认情况下原型对象就会获得一个constructor(构造函数)属性,这个属性又指向了我们创建的新函数。上面的例子Person.prototype.constructor,就是我们的Person上面例子用一张图片来说明一下

Person函数中的prototype属性指向了Person.prototype,同时Person.prototype.constructor又指向了Person函数,当我们实例化person1对象时,这个对象内部也含有一个prototype指针指向了Person.prototype对象。

在上面的例子中。Person对象的所有属性和方法都赋值给了原型对象,也就是在Person对象并没有这些属性,所以实例出来的person1对象中也没有这些属性,只有一个指向原型对象的指针,那么实例化出来的对象不是相当与没有东西。但是如果person1.name又是有数据的。这就涉及到了原型模式的搜索机制

(b)原型模式的搜索机制

原型对象的遍历方式,先从实例本身开始,搜索给定的属性的名称,所有实例中是否有这个属性的值,如果有就返回,如果没有就所有原型中是否存在,存在就返回这个属性的值
原型中会存在屏蔽原理,当我们为实例添加一个属性是,这个属性就会屏蔽原型中同名的属性,也就是当我们访问实例中的某个属性时,如果该属性存在,就会返回该属性不会在搜索原型中的同名属性属性,如果使用delete操作符删除实例中的属性时,就会回复对原型中同名属性的连接。

(c)原型模式的简写方式

Person.prototype = {
			name: ‘jiang‘,
			age: 14,
			job: ‘sf‘,
			sayName: function(){
				console.log(this.name);
			}
		}

  

以上重写后,起原型的constructor不再指向Person,而是指向了Object,因为这样设置的话就相当与一个以字面量形式创建的新对象,在本质上已经完全重写了默认的prototype对象,因此prototype的constructor不再指向原来的Person。除非自己指定constructor:Person。

//或者重设构造函数
		Object.defineProperty(Person.prototype, ‘constructor‘, {
			enumerable:false,
			value: Person
		});

这样的写法,就可以将原型对象中的构造函数属性重新指向了Person。

原型模式虽然解决了工厂模式和构造函数模式的缺点,当仍然不是完美的模式。这次先吹水吹到这了

原文地址:https://www.cnblogs.com/jiang-z/p/8146311.html

时间: 2024-11-11 22:09:30

javascript--面向对象(二、工厂模式,构造函数,原型模式)的相关文章

面向对象=====>工程模式/构造函数/原型模式

什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现.   工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象.其实现方法非常简单,也就是在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可. function createBlo

JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式

1.单例模式 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>面向对象之单例模式</title> 6 </head> 7 <body> 8 9 <script type="text/javascript"> 10 //对象数据类型

面向对象JS基础讲解,工厂模式、构造函数模式、原型模式、混合模式、动态原型模式

什么是面向对象?面向对象是一种思想!(废话). 面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样我们如果把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作.接下来将为大家讲解在JS中面向对象的实现. 工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,而由于在ECMAScript中无法创建类,因此用函数封装以特定接口创建对象.其实现方法非常简单,也就是在函数内创建一个对象,给对象赋予属性及方法再将对象返回即可. function createBlog(

浅议javascript的工厂模式,构造函数模式及原型模式

通常来讲我们一般这样创建对象: (1)  var jxj=new Object(); jxj.name="jxj"; jxj.sayHi=function(){console.log("O(∩_∩)O哈哈哈~")}: (2)  var   jxj={name:"jxj",age:"24",.....} 这两种方式在一些场景简单,规模小的项目中使用,我们还可以忍受:但这种方式在可拓展性,可维护性等等方面有很多的问题,于是,就出现

Javascript 构造函数模式、原型模式

前两天写完组合继承,打算总结一下原型继承的,不过今天看了一下工厂模式.构造函数模式和原型模式,觉得有必要总结一下以加深印象. ——————————————————————————————————————————————————————————————————————————————————碎碎念. 1.工厂模式 <Javascript 高级程序设计(第3版)> 用了寥寥十多行介绍了工厂模式.我找了一些相关资料,想确定一下这种模式的具体适用场景和优势.按照资料中的说法,是考虑到 ECMAScri

js设计模式:工厂模式、构造函数模式、原型模式、混合模式

一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.age = "27"; o1.msg = function(){ console.log("姓名:"+this.name+"  性别:"+this.sex+"  年龄:"+this.age); } var o2 = new Object(); o2.nam

js - 创建对象的几种方式(工厂模式、构造函数模式、原型模式)

原文引用https://www.dazhuanlan.com/2019/08/26/5d62f8b594f10/ 工厂模式 做法:内部创建一个对象,并未对象属性赋值并且返回 缺点:解决创建多个相识对象的问题,但不能识别创建的对象的类型 构造函数模式 做法:直接将属性和方法赋值给 this 对象,没有 return 语句 缺点:对象不是共用方法和属性,每 new 一次对象就要创建一个内存,超出性能消耗 原型模式 做法:通过 prototype 为对象添加属性 缺点:每个实例都共享属性方法,实例中修

JS面向对象(1)——构造函数模式和原型模式

1.构造函数模式 构造函数用来创建特定的类型的对象.如下所示: function Person(name,age,job){ this.name=name; this.job=job; this.age=age; this.sayName=function(){ alert(this.name); }; } var person1=new Person('nick',20,'student');var person2=new Person('nick',20,'student');alert(p

JavaScript创建对象的默认方式:组合使用构造函数模式和原型模式

由于 JavaScript中没有类,对象充当着一系列集合的模板,包含着属性和方法,而每个对象中也有一个原型对象,可以存放共享方法和属性 . 创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式.构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性 //组合使用构造函数模式(构造函数设置自己的属性)和原型模式(原型设计那些共享的方法和属性) function Person(name,age,job){ this.name=name; this.age=age; this.jo

7中创建对象的方式(工厂模式、构造函数模式、原型模式、动态原型模式等分析)

1.工厂模式 // 定义工厂函数 function createPerson(name, age, hobby) { // 创建一个临时object对象 var obj = new Object(); // 将工厂函数的参数赋值给临时对象 obj.name = name; obj.age = age; obj.hobby = hobby; obj.sayName = function() { console.log("我的名字叫:"+this.name); } // 返回这个包装好的临