📜  JavaScript原型

📅  最后修改于: 2020-09-27 07:35:42             🧑  作者: Mango

在本教程中,您将借助示例来学习JavaScript原型。

在学习原型之前,请务必查看以下教程:

  • 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()是对象构造函数。我们从中创建了两个对象person1person2


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';

然后对象person1person2继承了Person构造函数的原型属性的gender属性。

因此,对象person1person2都可以访问性别属性。

注意:将属性添加到对象构造函数的语法为:

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__已被弃用,您应该避免使用它。