JavaScript 创建对象 (工厂模式,web开发服务器

本文探讨JavaScript中的构造函数模式及其缺点,如创建多个同名Function实例和全局函数问题。通过将方法定义到原型上,可以避免这些问题,实现共享。然而,全局函数的使用仍然存在局限。原型模式则通过共享原型对象的属性和方法解决了这些问题,减少了内存消耗。同时介绍了原型模式的搜索机制和简洁的语法形式。
摘要由CSDN通过智能技术生成

[](

)构造函数模式的缺点


缺点一、会创建多个完成相同任务的同名Function实例

同上面的例子:


function Person(name,age,job){

	this.name = name;

	this.age = age;

	this.job = job;

	this.sayName = function(){

		console.log(this.name);

	}

}

var person1 = new Person('John',22,engineer);

var person2 = new Person('Lin',22,engineer); 

Person的两个实例person1和person2,各自都有一个sayName方法。但person1.sayName和person2.sayName不是一样的,即这两个方法各自都是Function的一个实例。

因为,ECMAScript的函数都是对象,其实可写作new Function():


this.sayName = function(){

	console.log(this.name);

}

//可以写作

this.sayName = new Function("console.log(this.name)"); 

也就是说:通过自定义构造函数模式,每通过 new Person()实例一个新的对象,也就创建了一个新的Function实例。每个person中的sayName方法是不一样的,是不同的实例。虽然他们之间有相同的名字、处理的代码相同。

每创建一个新的Person实例,就又附带创建了新的Function实例。而这些Function实例,同名又干一样的事情,确实是没有必要!

如何规避?

将Person中sayName函数的定义放到构造函数的外部,改写如下:


function Person(name,age,job){

	this.name = name;

	this.age = age;

	this.job = job;

	this.sayName = sayName;

}

function sayName(){

	console.log(this.name);

} 

相当于在构造函数Person内部的sayName属性设置为全局函数sayName()。this.sayName则是一个指针,指向这个全局函数。

这样就可以让多个Person实例的this.sayName属性都指向这个全局函数,从而没有创建过多的同名Function实例(干同样的事)。

缺点二、全局函数

看样子把构造函数内部的方法,定义到外部作全局函数就可以解决问题了。

但是这个定义在全局作用域的函数,却只能给某类对象使用,听起来就怪怪的。

还有,如果某构造函数需要很多方法,为了避免创建过多同名Function实例,难道我们要在全局作用域定义很多个函数吗?!

[](

)原型模式

===================================================================

原型模式可以改善构造函数模式的缺点:


function Person(){

	Person.prototype.name = 'John';

	Person.prototype.age = 22;

	Person.prototype.job = 'engineer';

	Person.prototype.sayName = function(){

		console.log(this.name);

	}

}

var person1 = new Person();

var person2 = new Person(); 

关于原型对象:

  1. 我们创建的函数都具有一个prototype属性,该属性是个指针,指向该函数的原型对象。

  2. 原型对象:可以让所有对象的实例共享它所包含的属性和方法

  3. 原型对象都有一个constructor属性,该属性也是个指针,指向prototype属性所在的函数。

因为Person.prototype原型对象,可以让Person的所有实例都共享它所包含的属性和方法。

那也就不会像构造函数模式那样,需要 创建许多同名Function实例 或者 在全局作用域定义许多个函数了。

在这里插入图片描述

即,Person.prototype指向原型对象;

Person.prototype.constructor指向Person;

Person创建的实例person1与person2,[[prototype]],仅仅指向Person.prototype(原型对象),与构造函数Person没有直接关系。

[](

)原型模式的搜索


当代码读取某个对象实例的某个属性时,是先从该实例上搜索查找有无该属性,若在实例本身check到了,那就返回该属性的值;如果在实例上找不到,那继续往上找,找实例的原型对象(Person.prototype)看有没有该属性。

这也是为什么不同实例能共享原型对象里的属性和方法。

[](

)简单的语法


可以这么写:


function Person(){};

Person.prototype = {

	name : 'John',

	age : 22,

	job : 'enginee',

	sayName : function(){

		console.log(this.name);

	}

}

var person1 = new Person;

console.log(person1.constructor == Object);//true;

console.log(person1.constructor == Person);//false; 

因为说过,Person.prototype会有个constructor属性,这个属性指向prototype属性所在的函数。可见prototype现在没有写在Person里面了,而是在Object上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值