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

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

这个问题本身存在预设偏差: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, ...),导致实例缺少属性。

立即学习“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]]。混淆语法表象和运行时本质,才是多数问题的源头。


# javascript  # es6  # java  # js  # node.js  # json  # node  # app  # 工具  # c++  # 面向对象编程 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 魔毅自助建站系统:模板定制与SEO优化一键生成指南  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  如何打造高效商业网站?建站目的决定转化率  如何在 React 中条件性地遍历数组并渲染元素  Java遍历集合的三种方式  Laravel怎么做数据加密_Laravel内置Crypt门面的加密与解密功能  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  详解Android图表 MPAndroidChart折线图  Laravel如何使用Sanctum进行API认证?(SPA实战)  Laravel怎么发送邮件_Laravel Mail类SMTP配置教程  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  如何快速搭建高效香港服务器网站?  ,南京靠谱的征婚网站?  JavaScript中的标签模板是什么_它如何扩展字符串功能  Python进程池调度策略_任务分发说明【指导】  简历在线制作网站免费版,如何创建个人简历?  黑客如何利用漏洞与弱口令入侵网站服务器?  网站制作大概多少钱一个,做一个平台网站大概多少钱?  图册素材网站设计制作软件,图册的导出方式有几种?  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  三星网站视频制作教程下载,三星w23网页如何全屏?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  矢量图网站制作软件,用千图网的一张矢量图做公司app首页,该网站并未说明版权等问题,这样做算不算侵权?应该如何解决?  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  千问怎样用提示词获取健康建议_千问健康类提示词注意事项【指南】  音乐网站服务器如何优化API响应速度?  如何在橙子建站中快速调整背景颜色?  如何快速完成中国万网建站详细流程?  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  制作旅游网站html,怎样注册旅游网站?  javascript中对象的定义、使用以及对象和原型链操作小结  Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】  HTML5建模怎么导出为FBX格式_FBX格式兼容性及导出步骤【指南】  Mybatis 中的insertOrUpdate操作  Python文件异常处理策略_健壮性说明【指导】  为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】  Laravel如何为API编写文档_Laravel API文档生成与维护方法  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  企业网站制作这些问题要关注  Swift中循环语句中的转移语句 break 和 continue  详解Oracle修改字段类型方法总结  在Oracle关闭情况下如何修改spfile的参数  b2c电商网站制作流程,b2c水平综合的电商平台?  Laravel如何创建自定义Artisan命令?(代码示例)  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】  Laravel如何实现多对多模型关联?(Eloquent教程)  Laravel如何使用Blade模板引擎?(完整语法和示例)