在学习原型之前,请务必查看以下教程:
- JavaScript对象
- JavaScript构造函数
如您所知,您可以使用对象构造函数在JavaScript中创建一个对象。例如,
// constructor function
function Person () {
this.name = 'John',
this.age = 23
}
// creating objects
let person1 = new Person();
let person2 = new Person();
在上面的示例中, function Person()
是对象构造函数。我们从中创建了两个对象person1
和person2
。
JavaScript原型
在JavaScript中,默认情况下,每个函数和对象都有一个名为prototype的属性。例如,
function Person () {
this.name = 'John',
this.age = 23
}
let person = new Person();
console.log(Person.prototype); // { ... }
在上面的示例中,我们尝试访问Person
构造函数的prototype属性。
由于prototype属性目前没有值,因此它显示一个空对象{…} 。
原型继承
在JavaScript中,可以使用原型向构造函数添加属性和方法。对象从原型继承属性和方法。例如,
// constructor function
function Person () {
this.name = 'John',
this.age = 23
}
// creating objects
let person1 = new Person();
let person2 = new Person();
// adding property to constructor function
Person.prototype.gender = 'male';
// prototype value of Person
console.log(Person.prototype);
// inheriting the property from prototype
console.log(person1.gender);
console.log(person2.gender);
输出
{ gender: "male" }
male
male
在上面的程序中,我们使用以下代码向Person
构造函数添加了新的属性gender
:
Person.prototype.gender = 'male';
然后对象person1
和person2
继承了Person
构造函数的原型属性的gender
属性。
因此,对象person1
和person2
都可以访问性别属性。
注意:将属性添加到对象构造函数的语法为:
objectConstructorName.prototype.key = 'value';
原型用于为构造函数创建的所有对象提供附加属性。
使用原型将方法添加到构造函数
您还可以使用原型向构造函数添加新方法。例如,
// constructor function
function Person () {
this.name = 'John',
this.age = 23
}
// creating objects
let person1 = new Person();
let person2 = new Person();
// adding a method to the constructor function
Person.prototype.greet = function() {
console.log('hello' + ' ' + this.name);
}
person1.greet(); // hello John
person2.greet(); // hello John
在上述程序中,使用原型将新方法greet
添加到Person
构造函数 。
改变原型
如果更改了原型值,则所有新对象都将具有更改后的属性值。所有先前创建的对象将具有先前的值。例如,
// constructor function
function Person() {
this.name = 'John'
}
// add a property
Person.prototype.age = 20;
// creating an object
let person1 = new Person();
console.log(person1.age); // 20
// changing the property value of prototype
Person.prototype = { age: 50 }
// creating new object
let person3 = new Person();
console.log(person3.age); // 50
console.log(person1.age); // 20
注意 :请勿修改标准JavaScript内置对象的原型,例如字符串,数组等。这被认为是不好的做法。
JavaScript原型链
如果对象尝试访问构造函数和原型对象中的相同属性,则该对象将从构造函数获取该属性。例如,
function Person() {
this.name = 'John'
}
// adding property
Person.prototype.name = 'Peter';
Person.prototype.age = 23
let person1 = new Person();
console.log(person1.name); // John
console.log(person1.age); // 23
在上面的程序,属性名在构造函数中,并在构造函数的原型财产申报。
程序执行时, person1.name
将在构造函数查找是否有一个名为name
的属性。由于构造函数的名称属性值为'John'
,因此该对象从该属性获取值。
程序执行时, person1.age
在构造函数查找是否有一个名为age
的属性。由于构造函数不具有age
属性,因此程序将查询构造函数的原型对象,并且该对象将从原型对象(如果有)中继承属性。
注意 :您还可以从对象访问构造函数的prototype属性。
function Person () {
this.name = 'John',
}
// adding a prototype
Person.prototype.age = 24;
// creating object
let person = new Person();
// accessing prototype property
console.log(person.__proto__); // { age: 24 }
在上面的示例中, person
对象用于使用__proto__
访问原型属性。但是, __proto__
已被弃用,您应该避免使用它。