一.es支持面向对象编程,但不使用类或接口。对象可以在代码执行过程中创建和增强,因此具有动态性而非严格定义的实体。
二.创建对象的方式
1.工厂模式:
(1)抽象了创建对象的具体过程
(2)缺:解决了创建多个相似对象的问题,但是却没有解决对象识别问题
function createperson (name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
}
var person1 = createperson("niki",20,"student");
2.构造函数模式
(1)创建自定义的构造函数,从而定义自定义对象类型的属性和方法
缺:每个方法都要在每个实例上重新创建一遍
function Person(name, age, job) {
this.name = name;
this,age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
(3)改进:
缺:在全局作用域中定义的函数实际上只能被某个对象调用,让全局作用域有点名不副实;
若果对象需要定义很多方法,就要定义很多全局函数,该自定义引用类型就没有任何封装性可言了。
function Person(name, age, job) {
this.name = name;
this,age = age;
this.job = job;
this.sayName = sayName;
}
function sayName() {alert(this.name);
}
var person1 = new Person("niki",20,"student");
3.原型模式
(1)每个函数都有一个prototype属性,该属性是一个指针,指向原型对象(它包含了由特定类型的所有实例共享的属性和方法),原型对象有一个contsructor属性,该属性回指构造函数。
(2)缺:它省略了为构造函数传递初始化参数这一环节,所有实例在默认情况下将取得相同的属性值
原型中所有属性是被很多实例共享的,这种共享对于函数非常合适,对于那些包含基本类型值的属性也说得过去,对于包含引用类型值的属性来说,问题比较大。
function Person(){
}
Person.prototype.name="niki";
Person.prototype.age = 29;
Person.prototype.job = "student";
Person.prototype..sayName=function(){
alert(this.name);
};
4.组合使用构造函数模式和原型模式-----使用最广,认同度最高的一种创建自定义类型的方法
(1)构造函数模式用于定义实例属性,原型模式定义方法和共享属性。
(2)优:每个实例都会有自己的一份实例属性的副本,同时又共享着对方法的引用,最大限度的节省了内存;
还支持向构造函数传递参数。
function Person(name,age,job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["AAA","BBB"];
}
Person.prototype = {
custructor:Person,
sayName:function(){
alert(this.name);
}
};
5.动态原型模式
(1)把所有信息都封装在了构造函数中,通过在构造函数中初始化原型,同时保持了使用构造函数和原型的优点(即通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型)
(2)注:使用动态原型模式,不能使用对象字面量重写原型,如果在已经创建了实例的情况下重写原型,会切断实例与新原型之间的联系。
unction 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);
};
}
}
6.寄生构造函数模式
(1)创建一个函数,作用仅仅是封装创建对象的代码,然后返回新创建的对象
(2)注:除了使用new操作符并把使用的包装函数叫构造函数之外,这个模式和工厂模式是一样的。构造函数在不返回值的情况下,默认返回新对象的实例,通过在构造函数末尾添加一个return语句,可以重写调用构造函数时返回的值
function createperson (name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
};
}
var person = new createPerson("niki",29,"student");(3)该模式可以在特殊情况下用来为对象创建构造函数,假设我们想创建一个具有额外方法的特殊数组,由于不能直接修改Array构造函数,可以使用该模式。
function SpecialArray(){
var values = new Array();
values.push.applay(values, arguments);
values.toPipedString = function(){
return this.join("|");
};
return values;
}
7.稳妥构造函数模式
(1)稳妥对象:没有公共属性,其方法也不引用this的对象。(最适合在一些安全的环境中,这些环境禁止使用this和new,或者在防止数据被其他应用程序改动时使用)
(2)注:稳妥构造函数遵循与寄生构造函数类似的模式,有2点不同:
新创建对象的实例方法不引用this;不使用new 操作符调用构造函数。
(4)与寄生构造函数模式类似,使用稳妥构造函数模式创建的对象与构造函数之间没有什么关系,因此instanceof操作符对这种对象没有意义。
function Person(name,age,job) {
var o = new Object();
//可以在这里定义私有变量和函数
o.sayName = function(){
alert(name);
};
return o;
}
var friend = Person("niki",20,"student");
(3)注:变量friend中保存的是一个稳妥对象,除了调用sayName()方法外,没有别的方式可以访问其数据成员,即使有其他代码给这个对象添加方法或数据成员,但也不可能有别的办法访问传入到构造函数中的原始数据,稳妥构造函数提供的这种安全性,使得他非常适合在某些安全的执行环境下使用。