【JS 】 创建对象
- 工厂模式
- 构造函数模式
- 原型模式
- 组合使用构造函数模式和原型模式
object构造函数或者对象字面量都可以用来创建单个对象,但是都有缺点:使用一个接口创建很多对象,会产生大量重复代码。人们开始使用工厂模式
1、工厂模式
object构造函数或者对象字面量都可以用来创建单个对象,但是都有缺点:使用一个接口创建很多对象,会产生大量重复代码。
考虑在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("jing",21,"web");
var person2 = createPerson("hao",21,"java");
函数createPerson可以根据接收的参数来构建一个包含所有必要信息的person对象,可以无数次的调用。
但是它没有解决一个对象识别的问题(怎么样知道一个对象的类型),因此新的模式出现了–构造函数模式
2、构造函数模式
构造函数可以用来创建特定类型的对象,还可以创建自定义的构造函数,从而定义自定义对象类型属性和方法
重写前面的例子
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person("jing",21,"web");
var person2 = new ePerson("hao",21,"ja");
- Person()取代了createPerson()
- 没有显示的创建对象
- 直接把属性和方法赋值给this
- 没有return语句
- 函数名Person()的首字母大写
要创建Person的新实例,必须使用new操作符
1、创建一个新的对象
2.将构造函数的作用域赋值给新的对象
3、执行构造函数的代码(给这个新对象添加属性)
4、返回新的对象
原型模式
理解原型对象:
1、创建一个新的函数,就会有特定的规则为其创建一个prototype属性,指向这个函数的原型对象(原型对象中包含可以由特定类型的所以实例共享的属性和方法)。
2、每个原型对象在默认情况下会获得一个constructor
(构造函数)属性,该属性指向该函数
3、当构造函数new了一个对象实例,这个对象实例上会有一个[[Prototype]]
指针,(也就是__proto__
属性),它也指向原型对象
原型模式创建对象
function Person(){
}
Person.prototype.name = 'jing',
Person.prototype.age = '21',
Person.prototype.job = 'stu'
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName();//'jing'
var Person2 = new Person();
Person2.sayName();//'jing'
alert(person1.sayName == person1.sayName);'true'
判断对象实例和原型对象是否存在关系
一、isPrototypeOf()
在所有实现中都无法访问到[[Prototype]],但是可以通过isPrototypeOf()方法来确定对象直接是否存在这种关系
console.log(Person.prototype.isPrototypeOf(person1));//true
console.log(Person.prototype.isPrototypeOf(person2));//true
二、Object.getPrototypeOf()
console.log(Object.getPrototypeOf(person1) == Person.prototype)//true
console.log(Object.getPrototypeOf(person2) == Person.prototype)//true
Object.getPrototypeOf()
方法可以方便地取得一个对象的原型
组合使用构造函数模式和原型模式
回顾:
构造函数模式用于定义实例属性
原型模式用于定义方法和共享的属性
好处:
每个实例都会有自己的一份实例属性副本,但同时有共享着对方法的引用,同时支持想构造函数传递参数
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.friends = ['wang','zhi'];
}
Person.prototype = {
constructor:Person,
sayName:function(){
console.log(this.name);
}
}
var person1 = new Person("jing",21,"web");
var person2 = new Person("hao",21,"java");
person1.friends.push('hao');
console.log(person1.friends);
console.log(person2.friends);
console.log(person1.friends === person2.friends);
console.log(person1.sayName === person2.sayName);
1、实例属性都是在构造函数中定义的
2、所有实例共享的属性constructor
和方法sayName()
在原型中定义
3、修改了person1.friends
,并不会影响person1.friends
,因为他们分别引用了不同的数组