JavaScript原型

一、原型介绍

JavaScript中没有"类"的概念,它通过原型prototype来实现对象间的属性和方法共享。既能节省内存,又能实现继承关系。

性质

  1. 共享性:所有实例共享原型上的属性和方法

  2. 动态性:可以随时修改原型,所有实例会立即受到影响

  3. 链式查找:当访问对象属性时,会沿着原型链向上查找

使用:

javascript 复制代码
//为数组拓展方法
const arr=new Array(3,4,5)
Array.prototype.max=function(){
	//利用环境对象this(谁引用指向谁)和展开运算符
	return Math.max(...this)
}
arr.max()->5
//输出5

//求和函数
Array.prototype.sum=function(){
	return this.reduce((prev,current)=>prev+current)
}
arr.sum()->12

将方法写在prototype上,实例就可以使用这些方法

二、constructor属性

每个函数在创建时,都会自动获得一个prototype属性,这个prototype对象会自动获得一个constructor属性,指回函数本身

constructor是原型对象上的一个重要属性,它建立了构造函数与原型对象之间的双向联系。

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

// 自动建立的关联
console.log(Person.prototype.constructor === Person) // true

constructor的重写问题:

javascript 复制代码
function Hello(){}

// 重写原型对象
Hello.prototype = {
    happy: function(){},
    sad: function(){}
}
// 此时constructor指向Object,而非Hello

// 正确的重写方式
Hello.prototype = {
    constructor: Hello, // 手动恢复constructor引用
    happy: function(){},
    sad: function(){}
}

关键点:

  • 直接赋值对象字面量会覆盖默认的prototype对象
  • 重写后必须显式设置constructor以保证原型链完整
  • 可以使用Object.defineProperty设置不可枚举的constructor属性

三、对象原型(proto)

当我们用new创建实例时,实例会链接到构造函数的prototype:

javascript 复制代码
const person1 = new Person('小明')
console.log(person1.__proto__ === Person.prototype) // 等价

使得实例能访问原型上的属性和方法。

__proto__用来表明当前实例对象指向哪个原型对象prototype,里面也有一个constructor属性,指向创建该实例对象的构造函数。

四、原型继承

JavaScript的继承是通过原型链实现的:

javascript 复制代码
function Student(grade) {
  this.grade = grade
}

// 让Student的原型指向Person的实例
Student.prototype = new Person()

const student1 = new Student(3)
console.log(student1.name) // undefined (但能通过原型链找到name属性)
console.log(student1.__proto__.__proto__ === Person.prototype) // true

示意:

复制代码
student1
    ↓ __proto__
Student.prototype
    ↓ __proto__
Person.prototype
    ↓ __proto__
Object.prototype
    ↓ __proto__
null

关键细节:

  1. 必须修复constructor指向

  2. 子类构造函数中需要调用父类构造函数(借用构造函数模式)

  3. 形成完整的原型链结构

五、完整关系图谱

  1. 构造函数:
  • 通过prototype属性指向其原型对象

  • 用于创建实例对象

  1. 原型对象:
  • 包含共享的属性和方法

  • 通过constructor属性指回构造函数

  • 自身的__proto__指向上一级原型Object.prototype

3.实例对象:

  • 通过__proto__指向构造函数的原型对象

  • 可以访问原型链上的所有属性和方法

补充说明:

所有原型链最终都指向Object.prototype

Object.prototype.__proto__为null

使用instanceof运算符可以检测原型链关系