面向对象的语言有一个标志,即拥有类的概念,抽象实例对象的公共属性与方法,基于类可以创建任意多个实例对象,一般具有封装、继承、多态的特性!但JS中对象与纯面向对象语言中的对象是不同的,ECMA标准定义JS中对象:无序属性的集合,其属性可以包含基本值、对象或者函数。可以简单理解为JS的对象是一组无序的值,其中的属性或方法都有一个名字,根据这个名字可以访问相映射的值(值可以是基本值/对象/方法)。
一、理解对象
1、基于Object对象
var person = new Object();
person.name = "my name";
person.age = 20;
person.getName = function(){
return this.name;
}
2、对象字面量方式(比较清楚的查找对象包含的属性及方法)
var person = {
name : "my name",
age : 20,
getName : function(){
return this.name;
}
}
二、创建对象
使用Object和对象字面量都可以创建对象,但缺点是创建多个对象时,会产生大量重复代码,所以下面的方法可以解决这个问题。
1、工厂模式
function createPerson(name, age, job) {
var obj= new Object();
obj.name = name;
obj.age = age;
obj.job = job;
obj.getName = function () {
return this.name;
}
return obj;
}
var person = createPerson('北落', 20, 'Web前端工程师');
创建对象交给一个工厂方法来实现,可以传递参数,但主要缺点是无法识别对象类型,因为创建对象都是使用Object的原生构造函数来完成的。
2、构造函数模式
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.getName = function () {
return this.name;
}
}
var person1 = new Person('北落', 20, 'Web前端工程师');
var person2 = new Person('南落', 21, 'PHP工程师');
使用自定义的构造函数(与普通函数一样,只是用它来创建对象),定义对象类型(如:Person)的属性和方法。它与工厂模式的区别在于:
- 没有显式地创建对象。
- 直接将属性和方法赋值给this对象。
- 没有return语句。
此外,要创建Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象创建;实际创建经过以下4个过程:
1、创建一个对象。
2、将函数的作用域赋给新对象(因此this指向这个新对象)。
3、执行构造函数的代码。
4、返回该对象。
3、原型模式
JS每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它是所有通过new操作符使用函数创建的实例的原型对象。原型对象最大特点是,所有对象实例共享它所包含的属性和方法,也就是说,所有在原型对象中创建的属性或方法都直接被所有对象实例共享。
function Person(){
}
Person.prototype.name = '北落';
Person.prototype.age = '20';
Person.prototype.job = 'Web前端工程师';
Person.prototype.getName = function(){
return this.name;
}
var person = new Person();
原型是指向原型对象的,这个原型对象和构造函数没有太大关系,唯一的关系是函数的prototype指向这个原型对象!而基于构造函数创建的对象实例也包含一个内部指针为[[prototype]]指向原型对象。
实例属性或方法的访问过程是一次搜索过程:
- 首先从对象实例本身开始,如果找到属性就直接返回该属性。
- 如果实例对象本身不存在要查找属性,就继续搜索指针指向的原型对象,在其中查找给定名字的属性,如果有就返回。
基于以上分析,原型模式创建的实例对象。
4、