📜  原型 - Javascript (1)

📅  最后修改于: 2023-12-03 14:50:31.527000             🧑  作者: Mango

原型 - Javascript

在Javascript中,每个对象都有一个原型对象,它是一个指向另一个对象的引用。当我们访问对象的某个属性时,如果该对象本身没有这个属性,那么Javascript就会沿着这个对象的原型链向上查找,直到找到这个属性或查到原型链的顶端为止。

原型与原型链

Javascript中的原型可以看作是一个对象定义的模板,它包含了这个对象所有属性和方法的定义。每个对象都有一个原型,当我们创建一个新对象时,Javascript会将其原型设置为父对象的原型。

let parent = {
  name: 'parent',
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

let child = {
  name: 'child',
  age: 10
};
child.__proto__ = parent;

child.sayHello(); // 输出:Hello, my name is child

在上面的代码中,child对象通过设置__proto__属性为parent对象的原型,继承了parent对象的sayHello方法。

如果在原型链中找不到所需的属性或方法,Javascript就会抛出一个ReferenceError错误。

原型继承

由于原型的存在,Javascript实现了一种简单而灵活的继承方式,称之为原型继承。在原型继承中,子对象继承父对象的所有属性和方法,包括原型的属性和方法。

function Parent() {
  this.name = 'parent';
}

Parent.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
}

function Child() {
  this.name = 'child';
}

Child.prototype = new Parent();

let child = new Child();
child.sayHello(); // 输出:Hello, my name is child

在上面的代码中,我们通过Child.prototype = new Parent()的方式实现了继承。由于Child.prototype通过new Parent()创建的实例继承了Parent.prototype上的属性和方法,因此Child的实例child具有了Parent的所有属性和方法。

ES6中的Class

ES6中加入了对Class的支持,使得Javascript可以更加像传统的面向对象语言。Class本质上还是通过原型实现的,并且支持继承。

class Parent {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Child extends Parent {
  constructor(name, age) {
    super(name);
    this.age = age;
  }
}

let child = new Child('child', 10);
child.sayHello(); // 输出:Hello, my name is child

在上面的代码中,Child通过extends关键字继承了Parent,并且通过super(name)调用了Parent的构造函数。

一些注意事项
  • 不要修改Object.prototype:Object.prototype是所有Javascript对象的顶级原型,如果修改它可能会导致代码中的其他对象产生意料之外的问题。
  • 构造函数的prototype属性不等于实例的原型:构造函数的prototype属性是新对象实例的原型,而非构造函数自身的原型。
  • 在原型链调用方法时注意this的指向:在原型链中调用方法时,方法中的this指向当前对象的原型,而不是当前对象本身。可以通过callapply方法修改this的指向。
结语

以上是Javascript中原型的基本概念、用法和注意点。掌握原型链和原型继承是Javascript开发中的重要基础知识,也是更深层次学习Javascript的基础。