0

0

为什么Javascript的面向对象与基于原型存在争议?

幻影之瞳

幻影之瞳

发布时间:2026-01-08 19:24:08

|

338人浏览过

|

来源于php中文网

原创

JavaScript是基于原型的,且天然支持面向对象编程;class只是原型机制的语法糖,所有继承和方法查找仍依赖[[Prototype]]链,this绑定取决于调用位置而非定义位置。

为什么javascript的面向对象与基于原型存在争议?

这个问题本身存在预设偏差:JavaScript 没有“面向对象与基于原型的争议”,它**就是基于原型的,且这种机制天然支持面向对象编程**。所谓“争议”,其实是初学者或从类语言(如 Java、C++)转来的开发者,对 class 语法糖和底层原型链关系理解不清晰导致的认知冲突。 下面直接说清楚几个关键点:

class 不是新范式,只是 prototype 的语法糖

ES6 引入的 class 关键字没有改变 JavaScript 的运行时模型——所有继承、方法查找、this 绑定依然依赖 [[Prototype]] 链。写一个 class Person,本质仍是操作 Person.prototype

常见误解:以为 class 声明后就生成了“类对象”,其实它只是函数:

class Person {}
console.log(typeof Person); // "function"
console.log(Person.prototype.constructor === Person); // true
  • class 内部方法默认不可枚举,但仍在 prototype
  • extends 实际调用的是 Object.setPrototypeOf(Sub.prototype, Super.prototype)
  • super() 在构造函数中,本质是调用父级 [[Construct]] 并绑定 this

new 与 Object.create() 的行为差异容易被忽略

两者都创建对象并设置原型,但初始化逻辑不同:

  • new Foo():执行 Foo 构造函数,this 指向新对象,返回该对象(除非显式返回非空对象)
  • Object.create(Foo.prototype):只设置 [[Prototype]],不执行任何初始化逻辑

错误做法:用 Object.create(Foo.prototype) 替代 new Foo() 后,忘记手动调用 Foo.call(newObj, ...),导致实例缺少属性。

ThinkPHP3.2.3完全开发
ThinkPHP3.2.3完全开发

ThinkPHP是一个快速、简单的基于MVC和面向对象的轻量级PHP开发框架,遵循Apache2开源协议发布,从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,尤其注重开发体验和易用性,并且拥有众多的原创功能和特性,为WEB应用开发提供了强有力的支持。 3.2版本则在原来的基础上进行一些架构的调整,引入了命名空间支持和模块化的完善,为大型应用和模块化开发提供了更多的便利。

下载

立即学习Java免费学习笔记(深入)”;

原型污染(Prototype Pollution)是真实风险,不是理论争议

因为所有对象共享原型链,恶意输入若被用于遍历赋值(如深拷贝、merge 工具),可能污染 Object.prototype

const obj = {};
obj.__proto__.polluted = "yes";
console.log({}.polluted); // "yes"
  • 常见触发点:lodash.mergeJSON.parse 后未校验 key、for...in 遍历时未用 hasOwnProperty
  • Node.js 中已多次出现因原型污染导致的 RCE(如 node-serialize
  • 修复方式:禁用 __proto__ / constructor 键;使用 Object.assign({}, input) 替代浅合并到目标对象

this 绑定混乱的本质是函数复用 + 原型链查找

方法从原型上被调用时,this 取决于调用位置,而非定义位置:

const obj = {
  name: "a",
  say() { console.log(this.name); }
};
const fn = obj.say;
fn(); // undefined —— this 指向 global / undefined(严格模式)
obj.say(); // "a"
  • 这不是 bug,是原型机制的自然结果:函数是独立值,obj.say 只是取值表达式
  • 解决方式不是“改成 class 就好了”,而是明确绑定:bind、箭头函数、或调用时用 call/apply
  • Class 字段中的箭头函数(method = () => {})能避免问题,是因为它把函数绑定到了实例,绕过了原型查找
真正需要警惕的,不是“该不该用 class”,而是是否意识到:你写的每一行 classnewsuper,背后都在读写 prototype[[Prototype]]。混淆语法表象和运行时本质,才是多数问题的源头。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

829

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

733

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

733

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

396

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

php学习网站大全
php学习网站大全

精选多个优质PHP入门学习网站,涵盖教程、实战与文档,适合零基础到进阶开发者,助你高效掌握PHP编程。

0

2026.01.09

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.1万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号