【Web前端】JavaScript 对象原型与继承机制

JavaScript 是一种动态类型的编程语言,其核心特性之一就是对象和原型链。理解原型及其工作机制对于掌握 JavaScript 的继承和对象关系非常重要。


什么是原型

每个对象都有一个内部属性 ​​[[Prototype]]​​​,这个属性指向创建该对象的构造函数的原型对象。这个内部属性通常被称为原型链(prototype chain)。原型链是 JavaScript 实现继承和属性查找的基础机制。


原型链的工作机制

原型链是一种用于实现继承的机制。当你访问一个对象的属性时,JavaScript 会首先在对象本身上寻找这个属性。如果在对象本身上找不到这个属性,它会沿着原型链向上查找,直到找到这个属性或者到达原型链的顶端。

代码示例

javascript 复制代码
const person = {
  name: 'Xianyu',
  age: 23
};

const child = Object.create(person);
child.job = 'Student';

console.log(child.name); // Xianyu
console.log(child.age); // 23
console.log(child.job); // Student

示例中 ​​child​​ 对象的原型是 ​​person​​ 对象。当我们访问 ​​child.name​​ 和 ​​child.age​​ 时,JavaScript 会首先在 ​​child​​ 对象上寻找这些属性。如果在 ​​child​​ 对象上找不到这些属性,它会沿着原型链向上查找,找到 ​​person​​ 对象上的 ​​name​​ 和 ​​age​​​ 属性。


设置原型

JavaScript 中有多种方式可以为一个对象设置原型。主要有三种方式:使用 ​​Object.create​​​、使用构造函数和自有属性。

使用 ​​Object.create​

​Object.create​​ 方法是 JavaScript 中为对象设置原型的最常用方式。它允许你创建一个新对象,并指定这个新对象的原型。

javascript 复制代码
const person = {
  name: 'Xianyu',
  age: 23
};

const child = Object.create(person);
child.job = 'Student';

console.log(child.name); // Xianyu
console.log(child.age); // 23
console.log(child.job); // Student

​child​​ 对象的原型是 ​​person​​​ 对象。


使用构造函数

构造函数是另一种为对象设置原型的方式。每个构造函数都有一个 ​​prototype​​ 属性,这个属性指向构造函数的原型对象。

javascript 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person = new Person('Xianyu', 23);
const child = new person.constructor();
child.job = 'Student';

console.log(child.name); // undefined
console.log(child.age); // undefined
console.log(child.job); // Student

示例中​​child​​ 对象的原型是 ​​Person.prototype​​。


自有属性

自有属性是对象本身上定义的属性,而不是通过原型链继承的属性。自有属性的优先级高于原型链上的属性。

javascript 复制代码
const person = {
  name: 'Xianyu',
  age: 23
};

const child = Object.create(person);
child.name = 'Xianyadan';
child.age = 22;
child.job = 'engineer';

console.log(child.name); // Xianyadan
console.log(child.age); // 22
console.log(child.job); // engineer

​child​​ 对象有自有属性 ​​name​​ 和 ​​age​​​,这些自有属性会遮蔽原型链上的同名属性。


属性遮蔽

属性遮蔽是指自有属性会遮蔽原型链上的同名属性。当你访问一个对象的属性时,JavaScript 会首先查找自有属性,如果找到了,就不会再沿着原型链向上查找。

代码示例

javascript 复制代码
const person = {
  name: 'Xianyu',
  age: 23
};

const child = Object.create(person);
child.name = 'Xianyadan';
child.age = 22;

console.log(child.name); // Xianyadan
console.log(child.age); // 22

示例中​​child​​​ 对象有自有属性 ​​name​​​ 和 ​​age​​,这些自有属性会遮蔽原型链上的同名属性。


原型与继承

JavaScript 通过原型链实现继承。继承是指一个对象可以继承另一个对象的属性和方法。通过设置对象的原型,我们可以实现对象之间的继承关系。

代码示例

javascript 复制代码
function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.sayHello = function() {
  console.log('Hello, I am ' + this.name);
};

function Student(name, age, grade) {
  Person.call(this, name, age);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

const student = new Student('Xianyu', 23, 'A');
student.sayHello(); // Hello, I am Xianyu
console.log(student.grade); // A

​Student​​ 构造函数通过调用 ​​Person​​ 构造函数来继承 ​​Person​​ 对象的属性和方法。​​Student.prototype​​ 被设置为 ​​Person.prototype​​ 的一个实例,从而实现了 ​​Student​​ 对象继承 ​​Person​​​ 对象的属性和方法。

相关推荐
明月_清风1 小时前
打字机效果优化:用 requestAnimationFrame 缓冲高频文字更新
前端·javascript
明月_清风2 小时前
Markdown 预解析:别等全文完了再渲染,如何流式增量渲染代码块和公式?
前端·javascript
掘金安东尼2 小时前
用 CSS 打造完美的饼图
前端·css
掘金安东尼10 小时前
纯 CSS 实现弹性文字效果
前端·css
牛奶10 小时前
Vue 基础理论 & API 使用
前端·vue.js·面试
牛奶10 小时前
Vue 底层原理 & 新特性
前端·vue.js·面试
anOnion11 小时前
构建无障碍组件之Radio group pattern
前端·html·交互设计
pe7er11 小时前
状态提升:前端开发中的状态管理的设计思想
前端·vue.js·react.js
SoaringHeart12 小时前
Flutter调试组件:打印任意组件尺寸位置信息 NRenderBox
前端·flutter
晚风予星12 小时前
Ant Design Token Lens 迎来了全面升级!支持在 .tsx 或 .ts 文件中直接使用 Design Token
前端·react.js·visual studio code