百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>JS教程> javascript面向对象的创建对象笔记
分享文章到:

javascript面向对象的创建对象笔记

发布时间:01/15 来源: 浏览: 关键词:
小编在学习js了,今天看一站长写了一篇关于javascript面向对象之创建对象的文章下面我整理了一下与各位朋友一起学习.

1工厂模式:
工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。由于ECMAScript无法创建类,所以开发人员就发明一种函数,用函数来封装以特定接口创建对象的细节。如下:

 代码如下

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(“gothic”,”21″,”f2e”);
var person2 =createPerson(“greg”,”27″,”Doctor”);

这里函数creatPerson()能够根据接受的参数来构建一个包含所有必要信息的person对象,可以无数次的调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。工厂模式虽然解决了创建多个相识对象的问题,但是却没有解决对象识别的问题(即如何让知道一个对象的类型),所以又有了下面的模式。
2.构造函数模式
ECMAScript中的函数可用来创建特定类型的对象。像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。当然我们也可以创建自定义的构造函数,从而定义 自定义对象类型的属性和方法。如下:

 代码如下

function person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name)
};
}
var person1 = new Person(“gothic”,21,”f2e”);
var person2 = new Person(“greg”,27,”Doctor”);

这里用构造函数模式把上面的例子重写了一遍。下面我们看下两个写法的区别:
Person()中的代码与CreatePerson()中的除了相同部分,还有以下不同
1)没有显示的创建对象;
2)直接将属性和方法赋予了this对象;
3)没有return语句。
PS:按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。不过构造函数本身也是函数,只是可以用来创建对象而已。
Constructor:构造函数属性。对象的constructor最初是用来标识对象类型的。但是要检测对象类型,还是用instanceof操作靠谱一点,如下:

 代码如下
alert(person1 instanceof Object); //true
alert(person2 instanceof Object); //true

创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型,而这正是构造函数模式胜过工厂模式的地方。这个例子里:
person1和person2之所以同时是Object的实例,是因为所有对象均继承自Object。

构造函数和其他函数的唯一区别就在于调用它们的方式不同。任何函数,只要通过new操作符来调用,那它就可以作为构造函数,而任何函数如果不通过new操作符来调用,那它和普通函数也不会有什么两样。用前面的例子举例:

 代码如下

//当作构造函数使用
var person = new Person(“gothic”,21,”f2e”);
person.sayName();//”gothic”

//作为普通函数调用 www.111cn.net
Person(“greg”,27,”Doctor”);
windows.sayName();//”greg”

//在另一个对象的作用域中调用
var o = new Object();
person.call(o,”K0risten”,25,”Nurse”);
o.sayName();//”kristen”

构造函数模式虽然好用,但是也不是没有缺点。它的主要问题就是每个方法都要在每个实例上重新创建一遍。说明白点就是这种方式创建函数,会导致不同的作用域和标识符解析,但创建function新实例的机制是相同的。因此不同实例上的同名函数是不想等的,可以用下面这个判断下:
alert(person1.sayName == person2.sayName); //false

3.原型模式
我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,这个对象的用途就是包含可以由特定类型的所有实例共享的属性和方法。使用原型对象的好处就是可以让所有对象实例共享它所包含的属性和方法。说明白点就是没必要在构造函数中定义对象实例的信息,而是可以将这些信息直接添加到原型对象中,如下:

 代码如下

function Person(){
}
person.prototype.name = “gothic”;
Person.prototype.age = 21;
Person.prototype.job =”f2e”;
Person.prototype.sayName = function(){
alert(this.name);

}
var person1 = new Person();
person1.sayName(); //”gothic”
var person2 = new Person();
person2.sayName(); //”gothic”
alert(person1.sayName == person2.sayName); //true

要理解原型模式的工作原理,必须要先理解ECMAScript中原型对象的性质。
原型模式也有缺点,它省略了为构造函数传递初始化参数这一环节,结果所有实例在默认情况下都将取得相同的属性值。原型模式最大的问题是由其共享的本性所导致的。
因为原型中所有属性是被很多实例共享的,这种共享对于函数很合适,但是对于包含引用类型值的属性来说,问题就比较突出,如下:

 代码如下

function(){

}
Person.prototype ={
constructor:Person,
name:”gothic”,
age:21,
job:”f2e”
friends:["Shelby","Court"],
sayName:function(){
alert(this.name);
}
} www.111cn.net
var person1 = new Person();
var person2 = new Person();
person1.friends.push(“Van”);
alert(person1.friends); //”Shelby,Court,Van”
alert(person2.friends); //”Shelby,Court,Van”
alert(person1.friends == person2.friends); //true

上面代码我们可以看到Person.prototype对象有一个名为friends属性,该属性包含一个字符串组,然后创建了Person的两个实例,向person1.friends引用的数组添加了一个字符串。由于friends数组存在于Person.prototype而不是person1里,所以刚刚添加修改的也会通过person2.friends反映出来。但是有时我们并不想让它在person2.prototype里反映,实例一般都有属于自己的属性。

4.组合使用构造函数模式和原型模式
创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。这样的好处就是每个实例都会有自己的一份实例属性的副本,但同时又共享着对方的引用,最大限度的节省了内存,而且这种混合模式还支持向构造函数传递参数;如下:

 代码如下

function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends=["SHelby","Court"];
}
Person.prototype = {
constructor:Person,
sayName:function(){
alert(this.name);
}
}
var person1 =new Person(“gothic”,21,”f2e”);
var person2 =new Person(“greg”,27,”Doctor”);
person1.friends.push(“Van”);
alert(person1.friends); //”Shelby,Count,Van”
alert(person2.friends); //”Shelby,Court”
alert(person1.friends === person2.friends); //false
alert(person2.friends === person2.friends); //true

这种构造函数与原型混成的模式是目前使用最为广泛,认同度较高的方法。

5动态原型模式
动态原型模式它把所有信息都封装在了构造函数中,而通过在构造函数中初始化原型,又保持了同时使用构造函数和原型的优点。如下:

 代码如下

function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
if(typeof this.sayName != “function”){
Person.prototype.sayName = function(){
alert(this.name);
};
}
}
var friend = new Person(“gothic”,21,”f2e”);
friends.sayName();

上面代码里的if语句只有在sayName()方法不存在的情况下,才会将它添加到原型中。这段代码只会在初次调用构造函数时才会执行。此后,原型已经完成初始化,不要再做什么修改了。
6.寄生构造函数模式
如果再上述几种模式下都不适用的情况下可以试试寄生构造函数模式
这个模式基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。如下:

 代码如下

function Person(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 friends = new Person(“gothic”,21,”f2e”);
friends.sayName() //”gothic”

这里除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。狗造函数在不返回值的情况下,会默认返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。
这个模式可以在特殊的时候用来为对象创建构造函数

关于寄生构造函数模式我们要注意:返回的对象鱼构造函数或者与构造函数的原型属性之间没有关系;也就是说,构造函数返回的对象与在构造函数外部创建的对象没有什么不同。也就是不能依靠instanceof操作符来确定对象类型,所以我建议还是不要使用这个模式。
7.稳妥构造函数模式
我们的Douglas同学发明了js中的“稳妥对象”这个概念.所谓的稳妥对象指的是没有公共属性,而且其方法也不引用this的对象,稳妥对象适合在一些安全的环境中使用。稳妥模式函数模式遵循与寄生构造函数类似的模式(也就是说instanceof操作符对这种对象也没用),但有两点不同:一是新创建的对象的实例方法不引用this,二是不使用new操作符调用构造函数。按稳妥模式的要求,我们可以重写:

 代码如下

function Person(name,age,job){
var o =new Object();
o.sayName = function(){
alert(name);
};
return o;
}

以上这个模式创建的对象除了使用sayName()方法之外,没有其他办法访问name的值。我们可以想下面使用稳妥的person构造函数。

 代码如下
var friend = Person(“gothic”,21,”f2e”);
friends.sayName(); //gothic

这样friends保存的是一个稳妥对象,除了调用sayName()方法外,没有别的方法可以访问器数据成员。所以说稳妥模式适合在某些安全执行环境下使用。

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有3人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板