前端知识速记—JS篇:原型与原型链

前端知识速记---JS篇:原型与原型链

在JavaScript中,原型和原型链是非常重要的概念,它们帮助我们理解对象的创建和继承机制。


1. 什么是原型?

在JavaScript中,原型是构造函数所关联的一个对象,它决定了通过该构造函数创建的所有实例所共享的属性和方法。概念可以进一步分解为以下几点:

1.1 构造函数的原型属性

每个构造函数都有一个特殊的prototype属性,它是一个对象,定义了所有通过该构造函数创建的实例所可以共享的属性和方法。

示例:
javascript 复制代码
function Person(name) {
    this.name = name;  // 实例属性
}

// 定义共享方法
Person.prototype.sayHello = function() {
    console.log(`你好,我是${this.name}`);
};

// 创建实例
const alice = new Person('Alice');
alice.sayHello();  // 输出:你好,我是Alice

在这个例子中,Person构造函数的原型对象(Person.prototype)中定义了sayHello方法。所有使用Person构造函数创建的实例都可以访问这个方法。

1.2 实例与原型的关系

当你创建一个新实例时,该实例内部定义了一个指向其构造函数原型的__proto__属性。通过这个属性,实例可以访问原型上定义的方法和属性。

示例:
javascript 复制代码
console.log(alice.__proto__ === Person.prototype);  // 输出:true

这里,alice.__proto__指向了Person.prototype,因此alice可以访问到sayHello方法。

1.3 访问构造函数

每个实例对象都有一个constructor属性,指向它的构造函数。这使得我们可以从实例中反向确认它的创建来源。

示例:
javascript 复制代码
console.log(alice.constructor === Person);  // 输出:true

这告诉我们,alice是通过Person构造函数创建的。


2. 什么是原型链?

原型链是JavaScript中实现对象继承的关键机制。它是由多个原型构成的链条,每个对象都有一个__proto__属性,指向其构造函数的原型对象。以下是关于原型链的详细说明:

2.1 原型链的结构

每个对象都有一个__proto__属性,这个属性指向其构造函数的原型。原型对象同样可以有自己的原型,如此层层递归,直到找到顶层原型Object.prototype,或者为null为止,形成一个原型链。

示例:
javascript 复制代码
console.log(alice.__proto__ === Person.prototype);  // 输出:true
console.log(Person.prototype.__proto__ === Object.prototype);  // 输出:true
console.log(Object.prototype.__proto__);  // 输出:null

2.2 属性查找

当你访问一个对象的属性或方法时,JavaScript会首先检查该对象自身(即实例)是否有这个属性。如果没有,JavaScript将沿着原型链向上查找,直到找到该属性或者到达链的顶端。

示例:
javascript 复制代码
console.log(alice.name); // 输出:Alice (直接在实例上找到)
console.log(alice.sayHello); // 输出:function (通过原型找到)
console.log(alice.age); // 输出:undefined (在实例和原型上都找不到)

总之,如果在实例对象中找不到某个属性或方法,JavaScript会沿着__proto__属性链向上搜索,直到找到为止。

2.3 顶级原型

原型链的顶层原型是Object.prototype,它包含了所有JavaScript对象的基本方法和属性。如果在原型链的顶端也没有找到所请求的属性或方法,返回undefined

示例:
javascript 复制代码
console.log(Object.prototype);  // 输出:Object {}
console.log(alice.toString);     // 输出:查看在原型链上获取到的toString方法

3. 原型链的继承示例

通过原型链,我们可以让一个构造函数的实例继承另一个构造函数的属性和方法。

3.1 示例分析

javascript 复制代码
function Animal() {}

// 在Animal的原型上定义一个方法
Animal.prototype.eat = function() {
    console.log('正在吃...');
};

function Dog(name) {
    this.name = name;
}

// Dog的原型继承自Animal的实例
Dog.prototype = Object.create(Animal.prototype);

// 在Dog的原型上定义一个方法
Dog.prototype.bark = function() {
    console.log(`${this.name}在叫!`);
};

// 创建Dog的实例
const dog = new Dog('小狗');
dog.eat();  // 输出:正在吃...
dog.bark(); // 输出:小狗在叫!

在这个例子中,Dog的原型通过Object.create(Animal.prototype)指向Animal的原型。这意味着Dog的实例不仅能调用bark方法(它自己定义的方法),还可以调用eat方法(从Animal继承的方法)。

相关推荐
吞掉星星的鲸鱼29 分钟前
使用高德api实现天气查询
前端·javascript·css
lilye6632 分钟前
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析
java·服务器·前端
....49233 分钟前
Vue3 + Element Plus + AntV X6 实现拖拽树组件
javascript·vue.js·elementui·antvx6
zhougl9962 小时前
html处理Base文件流
linux·前端·html
花花鱼2 小时前
node-modules-inspector 可视化node_modules
前端·javascript·vue.js
HBR666_3 小时前
marked库(高效将 Markdown 转换为 HTML 的利器)
前端·markdown
careybobo4 小时前
海康摄像头通过Web插件进行预览播放和控制
前端
TDengine (老段)4 小时前
TDengine 中的关联查询
大数据·javascript·网络·物联网·时序数据库·tdengine·iotdb
杉之5 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
喝拿铁写前端5 小时前
字段聚类,到底有什么用?——从系统混乱到结构认知的第一步
前端