原型
前言
在 JavaScript 中,原型(Prototype)是一种用于实现对象继承和代码复用的机制,是 JavaScript 核心的一部分。掌握原型可以帮助我们更高效地管理代码的结构和性能。
理解原型
我们可以通过在浏览器控制台中执行 new String() 创建一个字符串对象,并打印出来观察其结构。在展开对象的详细信息时,可以看到原型 ([[Prototype]]) 以及原型所包含的内容。
原型的种类
在 JavaScript 中,原型主要分为以下两种:显式原型 (prototype)隐式原型 (proto)
显示原型
定义:显式原型是构造函数所特有的属性,指向一个对象。 作用:提供共享的属性和方法,以节省内存和代码重复。
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name}`);
};
Person.prototype.work = "Coder";
const person1 = new Person("Alice");
const person2 = new Person("Bob");
person1.sayHello(); // 输出: Hello, my name is Alice
person2.sayHello(); // 输出: Hello, my name is Bob
console.log(person1.work); // 输出: Coder
console.log(person2.work); // 输出: Coder
console.log(person1.sayHello === person2.sayHello); // true,共享同一个 sayHello 方法
person1.prototype.work = "Student"; // 无效操作
console.log(person1.work); // 输出: Coder
隐式原型 (__ proto__)
定义:__ proto__ 是每个对象所特有的一个属性,指向构造函数的显式原型。 作用:用于在属性查找时建立与原型的连接。
function People() {
}
People.prototype.friend = 'zzz'; // 修改 prototype 上的属性
const person1 = new People(); // 创建实例对象
person1.friend = 'lll'; // 修改实例上的属性
console.log(person1.friend); // 输出实例上的属性
console.log(People.prototype.friend); // 输出原型上的属性
在属性查找时,JavaScript 引擎会沿着 __ proto__ 指向的原型链查找,直到找到属性或到达原型链终点。 每个对象的隐式原型指向其构造函数的显式原型。
new操作符的执行过程
new 操作符背后的原理:
- 创建一个新的空对象。
- 让构造函数执行,将属性添加到新对象上
- 将新对象的 __ proto__ 指向构造函数的 prototype。
- 返回这个新对象。
Car.prototype.run = "running";
function Car() {
this.name = "su7";
this.height = 1400;
}
let car = new Car();
console.log(car.run); // 输出: running
console.log(car.__proto__ === Car.prototype); // true
等价于以下代码:
function Car() {
let this = {};
this.__proto__ = Car.prototype;
this.name = "su7";
this.height = 1400;
return this;
}
原型链
定义:JavaScript 的继承是通过原型链实现的。如果对象本身没有某个属性或方法,JavaScript 引擎会沿着原型链查找。 结构: 每个对象都有一个隐式原型 (__ proto__)。 隐式原型指向构造函数的显式原型 (prototype)。
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function () {
console.log(`Hello, my name is ${this.name}`);
};
const person = new Person("Alice");
console.log(person.sayHello); // 从 Person.prototype 中找到 sayHello 方法
console.log(person.toString); // 从 Object.prototype 中找到 toString
原型链的结构如下:
person → Person.prototype → Object.prototype → null
如果原型链上没有找到某个属性或方法,就会返回 undefined。
是不是所有对象都有原型
不是
在极其特殊的情况下对象没有隐式原型 因为Object.create()创建的对象的隐式原型会继承里面的对象的现式原型 let c=Object.create(null) 这样创建的对象是不会有隐式原型的,也就是没有原型
结语
这是我学习的成果,很开心和大家分享,祝大家天天开心