JavaScript模式的简单介绍

javascript的工厂模式和构造函数的区别

先给你介绍下JS常用的几种模式

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:国际域名空间、虚拟空间、营销软件、网站建设、宽城网站维护、网站推广。

1.原始模式

//1.原始模式,对象字面量方式

var person = { 

name: 'Jack',

age: 18,

sayName: function () { alert(this.name); }

};

//1.原始模式,Object构造函数方式

var person = new Object();

person.name = 'Jack';

person.age = 18;

person.sayName = function () {

alert(this.name);

};

/*显然,当我们要创建批量的person1、person2……时,

每次都要敲很多代码,资深copypaster都吃不消!

然后就有了批量生产的工厂模式。*/

2.工厂模式

//2.工厂模式,定义一个函数创建对象

function creatPerson (name, age) {

var person = new Object(); 

person.name = name;

person.age = age;

person.sayName = function () {

alert(this.name);

};

return person; 

}

/*

工厂模式就是批量化生产,简单调用就可以进入造人模式(啪啪啪……)。

指定姓名年龄就可以造一堆小宝宝啦,解放双手。

但是由于是工厂暗箱操作的,所以你不能识别这个对象到底是什么类型、

是人还是狗傻傻分不清(instanceof 测试为 Object),

另外每次造人时都要创建一个独立的temp对象,代码臃肿,雅蠛蝶啊。

*/

3.构造函数

//3.构造函数模式,为对象定义一个构造函数

function Person (name, age) {

this.name = name;

this.age = age;

this.sayName = function () {

alert(this.name);

};    

}

var p1 = new Person('Jack', 18); //创建一个p1对象

Person('Jack', 18);   

//属性方法都给window对象,window.name='Jack',window.sayName()会输出Jack

4.原型模式

//4.原型模式,直接定义prototype属性

function Person () {}

Person.prototype.name = 'Jack';

Person.prototype.age = 18;

Person.prototype.sayName = function () { alert(this.name); };

//4.原型模式,字面量定义方式

function Person () {}

Person.prototype = {

name: 'Jack',

age: 18,

sayName: function () { alert(this.name); }

};

var p1 = new Person(); //name='Jack'

var p2 = new Person(); //name='Jack'

//这里需要注意的是原型属性和方法的共享,即所有实例中

//都只是引用原型中的属性方法,任何一个地方产生的改动会引起其他实例的变化。

5.混合模式(构造+原型)

//5. 原型构造组合模式,

function Person (name, age) {

this.name = name;

this.age = age;

}

Person.prototype = {

hobby: ['running','football'];

sayName: function () { alert(this.name); },

sayAge: function () { alert(this.age); }

};

var p1 = new Person('Jack', 20); 

//p1:'Jack',20; __proto__: ['running','football'],sayName,sayAge

var p2 = new Person('Mark', 18); 

//p1:'Mark',18;__proto__: ['running','football'],sayName,sayAge

//通过上面的例子,有什么区别一目了然

JavaScript 中介者模式与观察者模式有何不同

感觉二者非常像,都是pub/sub机制,如何进行区分?分别在什么不同的场景中进行应用?

在Obsever模式中, 不存在封装约束的单一对象。Observer 和 Subject 必须合作才能维持约束。

Communication(通讯)模式由观察者和目标互联的方式决定:单一目标通常有很多观察者,有时一个目标的观察者是另一个观察者的目标

Mediator 和 Observer 都能促进松耦合,然后Mediator 模式通过限制对象严格通过Mediator 进行通信来实现这个个目的

Observer 模式创建观察者对喜爱那个,观察者对象向订阅它们的对喜爱那个发布其感兴趣的事件。

在GoF的原文中是这样描述观察者模式的:

One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves.

具体应用场景是,当subject的某个动作需要引发一系列不同对象的动作(比如你是一个班长要去通知班里的某些人),与其一个一个的手动调用触发的方法(私下里一个一个通知),不如维护一个列表(建一个群),这个列表存有你想要调用的对象方法(想要通知的人);之后每次做的触发的时候只要轮询这个列表就好了(群发),而不用关心这个列表里有谁,只用关心想让谁加入让谁退出

这个列表就叫做ObserverList,它有一些维护列表方法:

function ObserverList(){

this.observerList = [];

}

ObserverList.prototype.Add = function( obj ){};

ObserverList.prototype.Empty = function(){};

ObserverList.prototype.Count = function(){};

ObserverList.prototype.Get = function( index ){};

ObserverList.prototype.Insert = function( obj, index ){};

ObserverList.prototype.IndexOf = function( obj, startIndex ){};

ObserverList.prototype.RemoveAt = function( index ){};

而我们的subject只用关心两件事:1.维护这个列表,2.发布事件

function Subject(){

this.observers = new ObserverList();

}

Subject.prototype.AddObserver = function( observer ){

this.observers.Add( observer );

};

Subject.prototype.RemoveObserver = function( observer ){

this.observers.RemoveAt( this.observers.IndexOf( observer, 0 ) );

};

Subject.prototype.Notify = function( context ){

var observerCount = this.observers.Count();

for(var i=0; i observerCount; i++){

this.observers.Get(i).Update( context );

// 在这里假设的是列表里的每个对象都有update方法,但个人觉得这个列表里也可以是不同对象的不同方法,只要能接受当前上下文作为参数, 可以这样执行:

// subscription.callback.apply( subscription.context, args );

}

};

中介模式(Mediator Pattern)

让我们假设这样一个场景: 有一个Manager一声令下,需要让工人A和工人B开工,代码可以是这样的

Manager.start = function () {

A.work();

B.work();

}

其实还可以这么写,新增一个中介模块,这个模块有存储了Manager的常用命令比如start,stop,resume,每一个命令其实维护的也是一个列表,比如start的列表下存储了所有员工的start方法:

Mediator["start"] = [

{

name: 'A',

callback: 'work'

},

{

name: 'B',

callback: 'workAgain'

},

]

所以Manager的方法可以重写为

Manager.start = function () {

Mediator.publish('start') // publish 为触发命令函数,以此来触发start命令下维护的所有回调函数

}

代码细节就不展示了,主要体现这么一个机制,而如果某个员工要提交自己的work方法供老板调用的话,只要注册一下就好了

2

Mediator.subscribe('C', function callback() {});

问题是新增加一个中介模块的好处是什么?

1.低耦合!如果不是经理要让员工开始工作,是董事长怎么办,或者是部门主管怎么办,难道都要这么写

XXX.start = function () {

A.work()

B.work();

}

都要把A.work什么抄一遍?当然不是,只要给中介模块发出命令就好了,

2.模块之间不需要进行通信,只要负责广播和监听事件就好了

3.在模块化的javascript中,中介模块能提高可维护性:是否启动某个模块,有没有权限启动某个模块,异步加载某些模块,模块之间的依赖关系,某些模块启动失败了怎么办。这些边界条件都可以交给它来判断,而其他模块只关心实现自己逻辑就好了

最后打个比方,中介模块真的就像房屋中介一样!如果你是房东,你只需要下令一声“我要找人租房”,他们就自然会生成那个列表,你不用直接和房客打交道。

javascript严格模式下有哪些不同

严格模式声明:“use strict”;

1、禁止变量未声明就赋值

2、限制动态绑定(属性和方法归属哪个对象在编译阶段就要确定)

1)禁止使用with

2)创建eval作用域,eval内声明的变量外部访问不到

3、增强的安全措施

1)禁止this关键字指向全局对象

2)禁止在函数内部遍历调用栈(函数内访问functionName.caller/functionName.arguments均报错)

4、禁止删除变量(只有configurable设置为true的对象属性才能被删除)

5、对只读属性赋值将会报错

6、重名错误

1)函数参数不能重名

7、禁止以零(0)开头的8进制表示法,支持数字0加字母o:“0o”为前缀表示八进制数

8、arguments的限制

1)arguments本身不能被赋值 ,但是arguments[x]仍然可以

2)arguments不再追踪参数的变化,在函数内改变参数值,arguments依然指向旧值

3)禁止使用arguments.callee,匿名函数无法调用自己了

9、函数必须在顶层声明

10、不允许使用以下保留字做变量名

1)implements

2)interface

3)let

4)package

5)private

6)protected

7)public

8)static

9)yield

《JavaScript设计模式》pdf下载在线阅读全文,求百度网盘云资源

《JavaScript设计模式》百度网盘pdf最新全集下载:

链接:

?pwd=i1tg 提取码:i1tg

简介:《JavaScript设计模式》共分六篇四十章,首先讨论了几种函数的编写方式,体会JavaScript在编程中的灵活性;然后讲解了面向对象编程的知识,其中讨论了类的创建、数据的封装以及类之间的继承;最后探讨了各种模式的技术,如简单工厂模式,包括工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式,以及外观模式,包括适配器模式。本书还讲解了几种适配器、代理模式、装饰者模式和MVC模式,讨论了如何实现对数据、视图、控制器的分离。在讲解MVP模式时,讨论了如何解决数据与视图之间的耦合,并实现了一个模板生成器;讲解MVVM模式时,讨论了双向绑定对MVC的模式演化。  

JavaScript创建对象的几种模式比较

第一种:Object构造函数创建

var Person = new Object();

Person.name = 'Nike';

Person.age = 29;

这行代码创建了Object引用类型的一个新实例,然后把实例保存在变量Person中。

第二种:使用对象字面量表示法

var Person = {};//相当于var Person = new Object();

var Person = {

name:'Nike';

age:29;

}

对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别不同

在介绍第三种的创建方法之前,我们应该要明白为什么还要用别的方法来创建对象,也就是第一种,第二种方法的缺点所在:它们都是用了同一个接口创建很多对象,会产生大量的重复代码,就是如果你有100个对象,那你要输入100次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装在函数体内,通过函数的调用直接生成对象。

第三种:使用工厂模式创建对象

function createPerson(name,age,job){

var o = new Object();

o.name = name;

o.age = age;

o.job = job;

o.sayName = function(){

alert(this.name);

};

return o;

}

var person1 = createPerson('Nike',29,'teacher');

var person2 = createPerson('Arvin',20,'student');

在使用工厂模式创建对象的时候,我们都可以注意到,在createPerson函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。

第四种:使用构造函数创建对象

function Person(name,age,job){

this.name = name;

this.age = age;

this.job = job;

this.sayName = function(){

alert(this.name);

};

}

var person1 = new Person('Nike',29,'teacher');

var person2 = new Person('Arvin',20,'student');

对比工厂模式,我们可以发现以下区别:

1.没有显示地创建对象

2.直接将属性和方法赋给了this对象

3.没有return语句

4.终于可以识别的对象的类型。对于检测对象类型,我们应该使用instanceof操作符,我们来进行自主检测:

alert(person1 instanceof Object);//ture

alert(person1 instanceof Person);//ture

alert(person2 instanceof Object);//ture

alert(person2 instanceof Object);//ture

同时我们也应该明白,按照惯例,构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。

那么构造函数确实挺好用的,但是它也有它的缺点:

就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法

第五种:原型创建对象模式

function Person(){}

Person.prototype.name = 'Nike';

Person.prototype.age = 20;

Person.prototype.jbo = 'teacher';

Person.prototype.sayName = function(){

alert(this.name);

};

var person1 = new Person();

person1.sayName();

使用原型创建对象的方式,可以让所有对象实例共享它所包含的属性和方法。

如果是使用原型创建对象模式,请看下面代码:

function Person(){}

Person.prototype.name = 'Nike';

Person.prototype.age = 20;

Person.prototype.jbo = 'teacher';

Person.prototype.sayName = function(){

alert(this.name);

};

var person1 = new Person();

var person2 = new Person();

person1.name ='Greg';

alert(person1.name); //'Greg' --来自实例

alert(person2.name); //'Nike' --来自原型

当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性。这时候我们就可以使用构造函数模式与原型模式结合的方式,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性

第六种:组合使用构造函数模式和原型模式

function Person(name,age,job){

this.name =name;

this.age = age;

this.job = job;

}

Person.prototype = {

constructor:Person,

sayName: function(){

alert(this.name);

};

}

var person1 = new Person('Nike',20,'teacher');


分享文章:JavaScript模式的简单介绍
URL链接:http://myzitong.com/article/dsgpcpo.html