深入理解JavaScript原型与原型链

深入理解JavaScript原型与原型链

在JavaScript中,原型(prototype)是一个核心概念,它不仅关乎对象的创建方式,还深刻影响着对象间的继承机制。本文将深入探讨原型的内涵、原型链的工作原理,以及为什么并非所有对象都拥有原型。

原型基础

每个JavaScript函数都自动配备了一个名为prototype的属性,这个属性是一个对象,用来定义当通过该函数作为构造函数创建新对象时,这些新对象(即实例)所共享的属性和方法。简而言之,原型就是构造函数创造实例的蓝图或原型模板。例如:

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

Person.prototype.sayHello = function() {
    console.log("Hello, my name is " + this.name);
};

在这个例子中,Person.prototype.sayHello定义了一个所有Person实例都可以访问的方法。

实例对象与原型的关系

当我们使用构造函数创建一个新对象时,这个新对象会自动链接到构造函数的原型对象上。这种链接是通过每个实例对象内部的特殊属性[[Prototype]](通常可访问的形式为__proto__,尽管不推荐直接使用)实现的。这意味着,实例对象可以访问其构造函数原型上的所有属性和方法,这一过程是隐式的,并且对于开发者来说是只读的。

js 复制代码
Person.prototype.like = '听歌'
function Person() {
    this.name = '田总'
}
let p = new Person()
p.like = '撸铁'

console.log(p.like); // 输出 撸铁

创建了Person的一个实例p,并为其显式地设置了一个同名属性like,值为'撸铁'。由于实例属性优先级高于原型属性,当访问p.like时,它会返回实例自身的like属性值,即'撸铁'

Constructor属性

每个实例对象都有一个constructor属性,它指向创建该实例的构造函数,这对于理解对象的来源非常有用。

js 复制代码
function Car() {
    this.name = 'su7'
}
let car = new Car()
console.log(car.Constructor);// 输出: [Function: Car]

// 实例对象通过constructor来记录我是由谁创建的

在JavaScript中,每个由构造函数创建的对象都会自动获得一个constructor属性,该属性指向创建该对象的构造函数。因此,当你打印car.constructor时,它会显示出Car构造函数本身,这表明car对象是由Car构造函数创建的。

原型链的奥秘

原型链 是JavaScript实现继承的主要机制。当访问一个对象的属性或方法时,如果该对象本身没有定义该属性或方法,JavaScript引擎会继续在其[[Prototype]]指向的对象中寻找,这个过程会一直向上追溯,直到找到该属性或方法,或者到达原型链的末端(null)。这个链式查找的过程确保了对象可以从其祖先那里继承属性和方法。

并非所有对象都有原型?

通常情况下,JavaScript中的每个对象都会有一个原型链,因为就连Object.prototype自身(所有对象原型的最终源头)也有一个null作为其原型,形成了原型链的终点。然而,有一种特殊情况:通过Object.create(null)创建的对象没有原型。这意味着该对象既没有继承自Object.prototype的默认方法(如toString()),也无法通过原型链查找机制获取任何属性或方法。这种对象常用于需要一个"纯净"对象,避免污染全局原型链的场景。

js 复制代码
let a = {
    num: 1
}

let b = Object.create(null);

这段代码在v8引擎中运行,对象a有原型,对象b由于通过Object.create(null)创建,所以该对象没有原型。

结论

原型和原型链是JavaScript实现面向对象编程和继承的核心机制。它们提供了一种灵活且高效的方式来管理对象的属性与方法,同时也允许我们通过构造函数和原型链来模拟经典的类继承模式。理解原型链的运作原理,特别是认识到并非所有对象都默认拥有原型这一特例,对于深入掌握JavaScript语言的精髓至关重要。在实际开发中,合理运用原型链,可以编写出结构清晰、易于维护的代码。

相关推荐
HEX9CF14 分钟前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
积水成江44 分钟前
关于Generator,async 和 await的介绍
前端·javascript·vue.js
Z3r4y1 小时前
【Web】portswigger 服务端原型污染 labs 全解
javascript·web安全·nodejs·原型链污染·wp·portswigger
人生の三重奏1 小时前
前端——js补充
开发语言·前端·javascript
计算机学姐1 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
Tandy12356_1 小时前
js逆向——webpack实战案例(一)
前端·javascript·安全·webpack
老华带你飞1 小时前
公寓管理系统|SprinBoot+vue夕阳红公寓管理系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·课程设计
小飞猪Jay1 小时前
面试速通宝典——10
linux·服务器·c++·面试
程序员陆通2 小时前
Spring Boot RESTful API开发教程
spring boot·后端·restful
qbbmnnnnnn2 小时前
【WebGis开发 - Cesium】如何确保Cesium场景加载完毕
前端·javascript·vue.js·gis·cesium·webgis·三维可视化开发