面向对象之创建对象
2019-04-12 本文已影响1人
itsmyturn
一,工厂模式
写法
本质:就是一个函数,通过传入函数内部需要参数,返回一个对象
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("Nicholas", 29, "Software Engineer")
var person2 = createPerson("Greg", 27, "Doctor")
优点:
封装好以后可以反复调用,解决了创建多个相似对象的问题
缺点:
不能解决对象识别问题(即怎么知道一个对象的类型)
二,构造函数模式
写法
function Person(name, age, job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}; }
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
与工厂模式的不同:
- 没有显示的创建对象
- 直接将属性和方法赋值给this对象
- 没有return语句
注意:构造函数函数名首字母大写,用来区分和其他普通函数不同。
通过new 操作符来实例化一个对象,中间经历了4个步骤
1. 创建一个新对象
2. 将构造函数的作用域赋给新对象(因此 this 就指向了这个新对象)
3. 执行构造函数中的代码(为这个新对象添加属性)
4. 返回新对象
person1 和 person2 分别保存着 Person 的一个不同的实例。这两个对象都
有一个 constructor(构造函数)属性,该属性指向 Person,如下所示
alert(person1.constructor == Person); //true
alert(person2.constructor == Person); //true
对象的 constructor 属性最初是用来标识对象类型的。但是,提到检测对象类型,还是 instanceof 操作符要更可靠一些。我们在这个例子中创建的所有对象既是 Object 的实例,同时也是 Person 的实例,这一点通过 instanceof 操作符可以
得到验证
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
使用(没有new,和普通函数无区别)
// 当作构造函数使用
var person = new Person("Nicholas", 29, "Software Engineer"); person.sayName(); //"Nicholas"
// 作为普通函数调用
Person("Greg", 27, "Doctor"); // 添加到window window.sayName(); //"Greg"
// 在另一个对象的作用域中调用
var o = new Object();
Person.call(o, "Kristen", 25, "Nurse"); o.sayName(); //"Kristen"
优点:
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型;而这正是构造函数模式 胜过工厂模式的地方
缺点:
每个方法都要在每个 实例上重新创建一遍,会导致不同的作用域链和标识符解析
三,原型模式
写法
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = 29;
Person.prototype.job = "Software Engineer";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //"Nicholas"
var person2 = new Person();
person2.sayName(); //"Nicholas"
alert(person1.sayName == person2.sayName); //true
原型链
优点
可以让所有对象实例共享它所包含的属性和方法,不必在构造函数中定义对象实例的信息,而是 可以将这些信息直接添加到原型对象中
缺点
新对象的这些属性和方法是由所有实例共享的
四,构造函数+原型混合模式
写法:
构造函数模式用于定义实 例属性,而原型模式用于定义方法和共享的属性
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("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
person1.friends.push("Van");
alert(person1.friends); //"Shelby,Count,Van"
alert(person2.friends); //"Shelby,Count"
alert(person1.friends === person2.friends); //false
alert(person1.sayName === person2.sayName);//true
优点
每个实例都会有自己的一份实例属性的副本, 但同时又共享着对方法的引用,最大限度地节省了内存.这种混成模式还支持向构造函数传递参 数;可谓是集两种模式之长