(一)、JavaScript原型
原型
JavaScript 是一门面向对象的编程语言,其中原型(prototype)是一个重要的概念,它提供了一种创建对象的方式,使对象可以共享属性和方法。在 JavaScript 中,每个对象都有一个原型,可以从原型中继承属性和方法。
原型的定义
JavaScript 的原型是一个对象,它包含了一些公共的属性和方法。当我们创建一个新的对象时,它会从它的构造函数的原型中继承这些属性和方法。JavaScript 的原型链是由每个对象的 [[Prototype]] 属性所连接的,这些属性指向它的原型对象。
我们可以通过给构造函数的 prototype 属性赋值来创建一个原型,也可以通过 Object.create() 方法创建一个原型对象。
// 创建原型的两种方式
// 方式一:通过构造函数的 prototype 属性创建
function Person() {}
Person.prototype.name = 'Tom';
Person.prototype.sayHello = function() {
console.log(`Hello, my name is ${this.name}.`);
};
// 方式二:通过 Object.create() 方法创建
const cat = { breed: 'Persian' };
const kitten = Object.create(cat);
kitten.name = 'Whiskers';
kitten.meow = function() {
console.log(`${this.name} says "Meow!"`);
};
在以上示例中,我们通过构造函数的 prototype 属性和 Object.create() 方法创建了两个不同的原型对象。其中,Person 构造函数的原型对象包含了 name 和 sayHello 属性和方法,而 cat 对象是一个普通对象,它的原型对象是 Object.prototype。
原型的原理
JavaScript 原型的原理是基于 JavaScript 的面向对象编程中的原型继承。在原型继承中,一个对象可以从另一个对象中继承属性和方法。当我们访问一个对象的属性或方法时,JavaScript 会先在该对象本身中查找,如果找不到,就会到该对象的原型对象中查找。如果还是找不到,就会到原型对象的原型对象中查找,一直到最顶层的 Object.prototype 对象为止。如果在查找过程中找到了对应的属性或方法,就会使用它。如果找不到,就会返回 undefined。
以下代码示例演示了原型继承的基本原理:
// 创建一个原型对象
const animal = {
makeSound() {
console.log('I am making a sound');
}
};
// 创建一个子对象,继承自原型对象
const cat = Object.create(animal);
cat.makeSound(); // I am making a sound
// 在子对象上添加新的属性和方法
cat.name = 'Whiskers';
cat.meow = function() {
console.log(`${this.name} says "Meow!"`);
};
cat.meow(); // Whiskers
在以上代码示例中,我们首先创建了一个原型对象 animal,它包含了一个 makeSound 方法。然后,我们使用 Object.create() 方法创建了一个新的对象 cat,它继承自 animal 原型对象,并且拥有了 makeSound 方法。最后,我们给 cat 对象添加了 name 属性和 meow 方法,它们只存在于 cat 对象本身中,而不是在 animal 原型对象中。
当我们调用 cat.makeSound() 方法时,JavaScript 首先在 cat 对象本身中查找,发现它没有 makeSound 方法,于是就去它的原型对象 animal 中查找。在 animal 原型对象中找到了 makeSound 方法,于是调用它并输出了字符串 "I am making a sound"。
当我们调用 cat.meow() 方法时,JavaScript 首先在 cat 对象本身中查找,发现它拥有 meow 方法,于是调用它并输出了字符串 "Whiskers says "Meow!""。
原型的规则
-
所有的对象都有一个原型对象(prototype)属性,指向它们的原型对象。
-
原型对象也是一个对象,因此也有自己的原型对象,即原型链的顶端是一个指向null的对象。
-
对象可以通过原型链访问到它们的原型对象上定义的属性和方法。
-
如果对象本身和原型对象都定义了同名的属性或方法,则对象本身的属性或方法优先级更高。
-
如果对象调用一个不存在于自身和原型对象中的属性或方法,则会沿着原型链向上查找,直到找到该属性或方法或者原型链的顶端为止。如果都找不到则返回undefined。
-
如果对象调用一个方法时,方法中的this关键字会指向该对象。
原型的应用
JavaScript 的原型机制在面向对象编程中发挥了重要的作用,它允许我们创建一个类或者对象的模板,然后通过继承来创建新的对象,从而大大减少了重复编写代码的工作量。
以下是一个使用原型继承的示例,它定义了一个 Animal 类和一个 Cat 类,其中 Cat 类继承自 Animal 类:
// Animal 类
function Animal(name) {
this.name = name;
}
Animal.prototype.makeSound = function() {
console.log('I am making a sound');
};
// Cat 类
function Cat(name) {
Animal.call(this, name);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.meow = function() {
console.log(`${this.name} says "Meow!"`);
};
// 创建 Cat 对象
const whiskers = new Cat('Whiskers');
whiskers.makeSound(); // I am making a sound
whiskers.meow(); // Whiskers says "Meow!"
在以上示例中,我们定义了一个 Animal 类和一个 Cat 类。Animal 类包含了一个构造函数和一个 makeSound 方法,Cat 类继承自 Animal 类,并包含了一个 meow 方法。我们通过在 Cat.prototype 对象上调用 Object.create() 方法,将 Cat.prototype 对象的原型对象设置为 Animal.prototype,从而实现了 Cat 类的继承。最后,我们创建了一个 Cat 对象 whiskers,并调用了它的 makeSound 和 meow 方法。
共享资源关注公众号获取
本文由 mdnice 多平台发布