/// <summary>/// 鸟类/// </summary>public class Bird{public void Fly(){Console.WriteLine("I can fly!");}}虽然JavaScript是一门面向对象编程语言,但它没有提供class的语法支持。function Person(){console.log("I am keepfool.");}JavaScript的“类”和构造函数是同时被定义的,在JavaScript中定义“类”时,就同时定义了构造器。var p = new Person();

定义属性和方法
现在我们已经定义好了Person类,可以为Person类添加一些属性和方法。
定义属性
在讲JavaScript对象时,我们讲了对象的属性设置和访问。
这段代码展示了定义对象属性的两种方式:
var cat = {color: "black"};cat.name = "Tom";console.log(cat.color);console.log(cat.name);使用this定义属性function Person(name){this.name = name;}•第一行代码,定义了Person类,并定义了构造函数。 var p1 = new Person("James");var p2 = new Person("Cury");在Chrome控制台中输出p1.name和p2.name

p1.name = "Lebron James";

function Person(name) {// 定义属性this.name = name;// 定义方法this.sayHello = function() {return "Hello, I am " + this.name;}}使用方法
constructor属性
当创建一个对象时,一个特殊的属性被JavaScript自动地分配给对象了,这个属性就是constructor属性。
在chrome控制台输入p1.constructor,可以看到p1对象的constructor属性指向一个函数。

瞧瞧这个函数的内容,这不正是Person()构造函数吗?

这表示我们也可以通过p1.constructor属性创建对象,
var p3 = new p1.constructor("Steve Nash");这行代码阐述了一句话:“我不关心p1对象是怎么创建的,但我想让另一个对象如p1一样创建!”

在Chrome控制台使用instanceof操作符,可以看到p1、p2、p3都是Person类的实例

另外,当我们以{}方式创建对象时,实际上也调用了Object()构造函数。
var o = {};这行代码声明了一个对象,尽管我们没有设置任何属性和方法,但JavaScript引擎默认给它设置了constructor属性。o.constructor指向的是Object()构造函数,[native code]显示了Object()是JavaScript内置的函数。
原型对象
在JavaScript中,定义一个函数时,函数就会拥有prototype属性,构造函数也不例外。
下图说明了Person()构造函数的prototype属性是一个对象,它是属于函数的,我们称这个属性为原型对象。
从Person类的角度出发,我们也可理解为prototype属性是属于Person类的。

同时Person类的实例是没有prototype属性的,上图的p1.prototype是undefined,这说明prototype属性是共享的,这有点像C#中的静态属性。
设置prototype
既然prototype是一个对象,那就可以为它添加属性和方法。
在函数的protpotype属性上定义属性和方法,与设置普通对象的属性和方法没什么区别。
下面的代码为Person.prototype定义了属性和方法。
function Person(name){this.name = name;this.sayHello = function() {return "Hello, I am " + this.name;}}// 在构造函数的prototype对象上定义属性和方法Person.prototype.height = 176;Person.prototype.run = function(){return "I am " + this.name + ", I am running!";}var p1 = new Person("James"); 使用prototype object.property的方式使用。
需要特别注意的是,name和sayHello()是属于Person类的实例,而height和run()是不属于Person类的实例。

小技巧:通过hasOwnProperty方法可以查看对象是否包含某个属性或方法。
自有属性 vs. prototype的属性
Person类的实例既可以使用Person类中的属性,又可以使用Person.prototype中的属性。
那么Person类的属性和Person.prototype的属性有什么差别呢?
首先,我们可以将Person类中的属性和方法理解为“实例属性”。
由于prototype是共享的,我们可以将prototype中的属性和方法理解为“共享属性”。
“实例属性”和“共享属性”的差别主要体现在性能上。
每创建一个Person的实例,就会产生一个name属性和sayHello()方法的副本,而height属性和run()方法则是所有实例共享一个副本。
既然如此,这意味着sayHello()方法可以提到prototype中。
另外,不同的Person实例height可能会不一样,应将它放到Person类中更合理。
function Person(name,height){this.name = name;this.height = height;}Person.prototype.sayHello = function(){return "Hello, I am " + this.name + ", my height is " + this.height + "cm.";}Person.prototype.run = function(){return "I am " + this.name + ", I am running!";}var p1 = new Person("James",203);var p2 = new Person("Cury",190); 