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

_江江江江      2022-02-16     176

关键词:

一、前言

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

二、创建对象的方式

(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。

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

 

javascript---面向对象:构造函数

首先javascript是基于对象的,即对象无处不在。本节我们来讲讲js的构造函数。创建对象实例有两种方法:第一种是工厂模式,第二种是构造函数 1.工厂模式1functionCreateObject(name,age){2varobj=newObject();3obj.name=name;4obj.age=age;5obj.run=fu... 查看详情

javascript的面向对象(代码片段)

JavaScript的面向对象(二)创建多个对象的方案创建对象方案:工厂模式构造函数模式什么是构造函数构造函数创建对象的过程构造函数+原型模式原型原型对象上的constructor构造函数+原型实现上述例子内存图构... 查看详情

面向对象之工厂模式和构造函数模式

工厂模式:用函数来封装,以特定接口来创建对象的细节。创建的对象是Object类型functionperson(name,age,job){varo=newObject();o.name=name;o.age=age;o.job=job;o.sayName=function(){alert(this.name);};returno;varperson1=newperson("cancan",21," 查看详情

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

什么是面向对象?面向对象是一种思想.面向对象可以把程序中的关键模块都视为对象,而模块拥有属性及方法.这样如果我们把一些属性及方法封装起来,日后使用将非常方便,也可以避免繁琐重复的工作. 工厂模式工厂模式是软... 查看详情

厘清面向对象四种模式:工厂模式构造函数模式原型模式混合模式(代码片段)

面向对象是一种方法,用来封装功能,方便日后使用,避免大量的重复工作 一、工厂模式(一)实现方法:在函数内创建一个对象并给对象赋予属性及方法,最终将对象返回。1functioncPerson(name,sex,age)2 varo=newObject();3 o.... 查看详情

javascript工厂模式和构造函数模式创建对象

...具体对象的过程(本书后面还将讨论其他设计模式及其在JavaScript中的实现)。考虑到在ECMAScript中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下面的例子所示。functioncreatePerson(name,age,j... 查看详情

javascript高级对象创建模式object对象字面量工厂模式自定义构造函数构造函数+原型

对象创建模式Object构造函数模式套路:先创建空Object对象,再动态添加属性/方法使用场景:起始时不确定对象内部数据问题:语句太多varp=newObject()p.name='Tom'p.age=12p.setName=function(name){this.name=name}p.setName('JACK')console.log(p.name,p.age)对... 查看详情

javascript创建对象之单例工厂构造函数模式

//单例模式解决分组问题让每个对象有自己的命名空间 varperson1={   name:"icss";   age:25; }; varperson2{   name:"sas";   age:26 } // 工厂模式实现同一事情的代码放在一个函数中其实就是函数的封装体现了高内聚低耦合 function... 查看详情

javascript面向对象-面试题实例

/从设计到模式  //设计模式简介  //设计  //模式  //分开  //从设计到模式    //23种设计模式      //创建型        //工厂模式(工厂方法模式,抽象工厂模式,建造者模式)        //单... 查看详情

javascript面向对象精要

四、构造函数和原型对象1.构造函数构造函数就是用new创建对象时调用的函数。使用构造函数的好处在于所有用同一个构造函数创建的对象都具有同样的属性和方法。functionPerson(){}varp1=newPerson();console.log(p1.constructor===Person);//truecon... 查看详情

javascript创建对象之单例工厂构造函数模式

01单例模式首先看一个问题,我们要在程序中描述两个人,这两个人都有姓名和年龄,可能刚刚开始学习js的时候会写成这样:1varname1=‘iceman‘;2varage1=25;34varname2=‘mengzhe‘;5varage2=26;以上的写法的确是描述两个人,每个人都有姓... 查看详情

面向对象

扩展面向对象术语 OOA面向对象分析 OOD面向对象设计 OOP面向对象编程对象的创建方式 1、字面量的创建方式 varobj= 缺点:多个同类对象创建时代码重复2、使用工厂模式创建对象(设计模式之--工厂模式) 定义一个工厂 functionstud... 查看详情

面向对象的程序设计-创建对象(代码片段)

本章内容工厂模式构造函数模式原型模式组合使用构造函数模式和原型模式动态原型模式寄生构造函数模式稳妥构造函数模式Object构造函数或对象字面量都可以用来创建单个对象,缺点是:使用同一个接口创建很多对象,会产生... 查看详情

2.工厂模式==》对象

...利用率(高密度低耦合)。没有继承和多态。3.构造函数==》对象要求:1.函数名首字母必须要大写2.里面的属性前面必须要加this。3.函数调用的时候必须使用new关键字string的类是String数组的类是Array对象的类是Object我们把person叫类。... 查看详情

javascript学习5js面向对象(代码片段)

创建对象的几种常用方式1.使用Object或对象字面量创建对象2.工厂模式创建对象3.构造函数模式创建对象4.原型模式创建对象1.使用Object或对象字面量创建对象JS中最基本创建对象的方式:varstudent=newObject();student.name="easy";student.age="2... 查看详情

面向对象(2)构造函数原型原型链的理解

...                         面向对象(2)原型原型链的理解1.面向对象的目的就是生成对象object。2.生成对象的方式  (1)单例模式(字面量定义)varobj=  (2)类的实例varobj=newObject()  (3)... 查看详情

面向对象

Js面向对象的几种方式?1.对象的字面量varobj={};2.创建实例对象varobj=newObject();3.构造函数模式functionfn(){},newfn();4.工厂模式:用一个函数,通过传递参数返回对象5.原型模式functionclock(hour){}fn.prototype.hour=0;newclock();1、工厂模式: ... 查看详情

“工厂构造原型”设计模式

我们可以明显的感受到:JS要实现面向对象(继承的能力),离不开这3种设计模式;原型链+构造函数=组合继承本篇带来一个新的继承方式:寄生继承,它由工厂模式和构造函数模式组成,即工厂+构造函数=寄生继承正文正是由... 查看详情