深入学习 JavaScript 原型和原型链
发布时间: 2023-12-15 07:42:54 阅读量: 34 订阅数: 40
JS原型与原型链的深入理解
# 1. 理解 JavaScript 中的原型
### 1.1 JavaScript 原型的概念
在 JavaScript 中,每个对象都有一个原型(prototype)。原型是其他对象的基础,它可以定义对象共享的属性和方法。当我们创建一个对象时,JavaScript 引擎会自动为该对象分配一个原型,我们可以通过 `Object.getPrototypeOf()` 方法来访问对象的原型。
示例代码:
```javascript
// 创建一个对象
let person = {
name: 'John',
age: 25,
greet: function() {
console.log('Hello, my name is ' + this.name);
}
};
// 获取对象的原型
let prototypeOfPerson = Object.getPrototypeOf(person);
console.log(prototypeOfPerson); // 输出:{}
```
在上述示例中,我们创建了一个 `person` 对象,然后通过 `Object.getPrototypeOf()` 方法获取了 `person` 对象的原型。在这个例子中,`prototypeOfPerson` 是一个空对象,这是因为 `person` 对象的原型是 `Object.prototype`。这说明所有对象都是从 `Object.prototype` 继承属性和方法的。
### 1.2 创建对象的方式:构造函数、工厂函数和原型
在 JavaScript 中,我们可以使用构造函数、工厂函数或者原型来创建对象。每种方式都有自己的特点和适用场景。
- 构造函数:使用 `new` 关键字来创建对象,构造函数中的 `this` 指向新创建的实例对象。
示例代码:
```javascript
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
// 创建实例对象
let john = new Person('John', 25);
```
- 工厂函数:返回一个新的对象实例,但不能识别对象的类型。
示例代码:
```javascript
// 工厂函数
function createPerson(name, age) {
return {
name: name,
age: age
};
}
// 创建对象实例
let jane = createPerson('Jane', 30);
```
- 原型:使用原型来共享对象的属性和方法,可以节省内存空间。
示例代码:
```javascript
// 使用原型来共享属性和方法
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log('Hello, my name is ' + this.name);
};
let peter = new Person('Peter', 28);
peter.greet(); // 输出:Hello, my name is Peter
```
### 1.3 __proto__ 和 prototype 的关系
在 JavaScript 中,每个对象都有一个 `__proto__` 属性,它指向该对象的原型。另外,构造函数也有一个 `prototype` 属性,它指向构造函数的原型对象。这两者之间存在着一定的联系。
示例代码:
```javascript
// 构造函数
function Animal(name) {
this.name = name;
}
// 原型方法
Animal.prototype.greet = function() {
console.log('Hello, my name is ' + this.name);
};
let cat = new Animal('Kitty');
console.log(cat.__proto__ === Animal.prototype); // 输出:true
```
在上述示例中,我们创建了一个 `Animal` 构造函数,并将 `greet` 方法添加到 `Animal` 的原型对象上。通过 `console.log(cat.__proto__ === Animal.prototype)` 我们可以看到,`cat.__proto__` 指向了 `Animal.prototype`,这说明在 JavaScript 中对象和原型之间是通过 `__proto__` 属性进行关联的。
以上是 JavaScript 原型的基本概念和相关知识,接下来我们将继续探索 JavaScript 中的原型链。
# 2. 探索 JavaScript 中的原型链
在前一章节中,我们已经了解了 JavaScript 中原型的概念及其作用。而原型链是 JavaScript 中一个非常重要的概念,它通过将对象的原型链接起来,形成一个链式的原型关系。
### 2.1 什么是原型链
原型链是 JavaScript 中实现对象的继承机制的一种方式。每个对象都有一个隐式的内部属性,称为原型(prototype)。通过这个原型,对象可以访问其他对象的属性和方法。
当我们访问一个对象的属性或方法时,如果该对象本身不存在该属性或方法,JavaScript 引擎会自动去对象的原型上查找。如果原型上还不存在,则会继续追溯原型的原型,最终找到或到达 Object.prototype(所有对象都能访问的原型)为止,这就形成了原型链。
简单来说,原型链就是通过对象与对象之间的原型关系形成的一条链,用于实现对象之间的属性和方法的继承。
### 2.2 原型链的构建过程
让我们通过一个示例来具体了解原型链的构建过程:
```javascript
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log('Hello, my name is ' + this.name);
}
function Student(name, grade) {
Person.call(this, name); // 调用父类的构造函数
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.study = function() {
console.log('I am studying in grade ' + this.grade);
}
var jack = new Student('Jack', 3);
jack.sayHello(); // 输出:Hello, my name is Jack
jack.study(); // 输出:I am studying in grade 3
```
在上面的代码中,我们定义了一个 Person 构造函数,它有一个原型方法 sayHello。然后我们定义了一个 Student 构造函数,它通过调用父类的构造函数,并使用 `Object.create()` 方法将父类的原型作为自己的原型。最后,我们通过 new 操作符创建了一个名为 jack 的 Student 对象,并调用了其继承自父类和自身的方法。
通过上述代码,我们可以看到原型链的构建过程:`Student -> St
0
0