大多数编程语言如java,c#,其面向对象都有两个明确的基本概念,即类和实例。类是对象的类型模板,例如,用Worker来表示一个工人类,用Student来表示一个学生类,类不表示
任何具体的事物;实例是根据类创建的对象,例如要表示小明是一个学生,就可以在Student中创建‘小明’这样一个对象。然而在JavaScript的世界里,没有类的概念。
JavaScript通过原型(prototype)来实现面向对象编程。
假设现在有一个这样的对象:

1
2
3
4
5
6
7
8
//创建一个名为Student的对象
var Student = {
name: 'xiaoming',
height: 172,
eat: fucntion () {
console.log(this.name+'is eating..');
}
};

那么如何来创建一个‘小明’呢?JavaScript通过一个Object.create()方法来传入一个原型对象,并创建一个基于该原型的新对象。下面通过编写一个函数
来实践上面讲到的。

1
2
3
4
5
6
7
8
//函数名为creatStudent
function createStudent (name) {
var x = Object.create(Student);
x.name = name;
return x;
}
var xiaoming = createStudent('小明');
xiaoming.eat(); //小明现在拥有父类eat这个方法了,能"吃"

当然,也可以不编写函数,直接在创建一个xiaoming的对象,然后通过xiaoming.proto = Student;同样可以实现,只不过不推荐采用这种方式,因为
万恶的低版本IE不兼容proto这个属性.

创建对象

JavaScript中每一个对象都会有一个原型,当我们用obj.xxx去调用一个对象的属性时,JavaScript引擎会先在当前对象上寻找,如果找不到就去到原型对象上寻找,如果还没找到,
就去到Object.prototype(最外层)找,最终还没找到就只能返回undefined了。
例如,创建一个Array数组,来看看它的原型链

1
2
var arr = [1,2,3];
arr--->Array.prototype--->Object.prototype--->null

构造函数

除了使用{…}创建一个对象外,还可以使用构造函数来创建。下面定义一个构造函数

1
2
3
4
5
6
function Student(name) {
this.name = name;
this.hello = function (){
alert('hello,'this.name+'!');
}
}

也许这个函数看起来跟普通函数没什么两样,JavaScript通过一个关键字new来实例化一个对象,

1
2
3
var xiaoming = new Student('小明');
xiaoming.name; //小明
xiaoming.hello(); //hello,小明!

试试如果不写new的话,上面的代码运行会如何!
此时新创建的xiaoming的原型链是:

1
xiaoming-->Student.prototype--->Object.prototype--->null

用new Student创建的对象还会从原型上获得一个constructor属性,它指向函数Student本身。
需要注意一个小问题,假设现在xiaoming,xiaohong来自对象Student.来看下面这段代码:

1
2
3
4
5
xiaoming.name;  //小明
xiaohong.name; //小红
xiaoming.hello; //function: Student.hello()
xiaohong.hello; //function: Student.hello()
xioaming.hello === xiaohong.hello; //false

xiaoming和xiaohong居然不是同一个函数!这就带来这样的问题,当我们创建很多对象的时候,就会产生很多不同的函数,虽然它们的名称和代码是相同的,这极大地浪费了内存,
所以我们需要让这些hello函数实际上只共享一个函数就行,也就是下面这段修改后的代码:

1
2
3
4
5
6
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () { //通过prototype来实现所有子对象共享父对象的函数
alert('hello,'+this.name+'!');
};

PS:以上是个人学习js面向对象的一些不成熟不全面的总结,想了解更多关于js面向对象的知识,推荐廖雪峰的js面向对象教程以及阮一峰的网络日志