在阅读这篇文章时,请你先清空脑中所有对原型一知半解的印象,首先来看Javascript中函数所具有的一个属性:prototype
.
先看下面这个例子:
function f() { } // define a function f
console.log(f.prototype.constructor === f); // true
当我们创建一个函数f
,这个函数会自动具有一个属性prototype
,这个属性即为函数f
的原型。并且这个它的原型自动会具有一个属性constructor
,指向函数f
。这里我们可以看出一种一一对应关系,即一个函数具有一个原型,而这个原型又通过属性constructor
指明它是哪一个函数的原型。
可是原型有什么用呢?让我们来看一个创建对象的例子:
function Car(brand, year) {
this.brand = brand;
this.year = year;
} // 定义一个函数Car
let car = new Car("玛莎拉蒂", 2014); // 从函数Car创建一个对象
console.log(car.brand); // 玛莎拉蒂
console.log(car.year); // 2014
console.log(car.has_wheels); // undefined,因为我们没有定义has_wheels属性
car.drive(); // 报错,因为我们没有定义drive函数
上面的代码中,brand
和year
都是每一辆车所独有的,但属性has_wheels
与函数drive
刚是所有的车所共有的。下面的代码展示了,如何用原型来实现这种“共有”的属性和函数。
function Car(brand, year) {
this.brand = brand;
this.year = year;
} // 定义一个函数Car
Car.prototype.has_wheels = true;
Car.prototype.drive = function() {
console.log("driving...");
}
let car = new Car("玛莎拉蒂", 2014); // 从函数Car创建一个对象
console.log(car.brand); // 玛莎拉蒂
console.log(car.year); // 2014
console.log(car.has_wheels); // true
car.drive(); // 打印出driving
从上面的代码,我们可以很容易地了解到Javascript对于面向对象的设计思想,那就是
- 使用new函数并配合构造函数(constructor)来创建对象,
- 运行构造函数(constructor)来设置对象“独有”的属性和方法,
- 对构造函数(constructor)的
prototype
进行更改可以对所有由它创建的对象设置“共有”的属性和方法。
要注意的是,只有函数有prototype
属性,也就是说只有函数有原型,而非函数的对象是没有的。
更多关于原型的探讨请参见:
网友评论