javascript原型链如何工作_怎样理解原型继承与类语法糖【教程】
发布时间 - 2026-01-30 00:00:00 点击率:次原型链查找属性时,先查对象自身,再沿__proto__逐级向上,直到Object.prototype.__proto__ === null为止;写属性默认只改自身,不污染原型。
原型链怎么查找属性?一句话说清机制
当你写 obj.method(),JS 先查 obj 自身有没有 method;没有就顺着 obj.__proto__ 找,再没就继续找 obj.__proto__.__proto__,直到碰到 Object.prototype.__proto__ === null 停止。这个“一级一级往上翻家谱”的过程就是原型链查找。
- 所有普通对象的终点都是
Object.prototype,所以都能用toString()、hasOwnProperty() - 数组、函数、日期等内置类型也走这条路:比如
[].push是从Array.prototype→Object.prototype→null - 写属性(如
obj.x = 1)默认只改自身,不会污染原型——这是避免意外共享的关键设计
为什么 Child.prototype = Parent.prototype 是危险操作?
这会让子类和父类共用同一份原型对象,改一个就等于改两个。比如你给 Child.prototype.sayHi 赋值,Parent 实例也会突然多出这个方法——这不是继承,是“原型污染”。
- 正确做法是用
Object.create(Parent.prototype),它新建一个空对象,并把它的__proto__指向Parent.prototype - ES6 的
class A extends B底层干的就是这事:A.prototype.__proto__被设为B.prototype,同时保留A.prototype.constructor指向A - 漏掉
constructor重置会导致instanceof或序列化时出问题,例如new A() instanceof A可能返回false
new Foo() 到底发生了什么?三步拆解
不是语法魔法,是明确的三步执行:
- 创建一个空对象,内部
[[Prototype]]指向Foo.prototype(即obj.__proto__ === Foo.prototype) - 以该对象为
this执行Foo.call(obj, ...args),把实例属性挂到对象上 - 如果构造函数显式返回一个对象,则返回它;否则返回刚创建的对象
这意味着:构造函数里定义的属性(如 this.name)属于每个实例;而挂在 Foo.prototype 上的方法(如 Foo.prototype.say)被所有实例共享——这才是内存友好的关键。
类语法糖(class)掩盖了哪些原型细节?
class 看起来像 Java,但底层完全依赖原型链。比如这段代码:
class Animal { constructor(name) { this.name = name; } speak() { console.log(this.name + ' makes a noise'); } }
class Dog extends Animal { constructor(name, breed) { super(name); this.breed = breed; } speak() { consol
e.log(this.name + ' barks'); } }
它等价于手动设置原型链 + 调用 super(),而 super() 本质就是确保子类构造函数里能正确访问父类的 this 和原型方法。但要注意:
-
extends null是合法的,此时Dog.prototype.__proto__为null,不再继承Object.prototype的方法(toString就会报错) - 静态方法(
static method)其实是挂在构造函数本身上的,即Dog.method()→Dog.__proto__.method(),和实例原型链无关 - 箭头函数不绑定
this,在类方法中用箭头函数定义回调时,this会指向定义时的实例,而不是调用时的上下文——这点和原型链无关,但常被误认为是“继承问题”
真正容易被忽略的,是原型链的动态性:你在运行时改 Animal.prototype.speak,所有已存在的 Dog 实例也会立刻生效——这不是 bug,是设计,但也是调试时最让人抓狂的点之一。
# javascript
# es6
# java
# js
# 为什么
# speak
# Static
# Array
# Object
# NULL
# 父类
# 子类
# 构造函数
# 继承
# class
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何用免费手机建站系统零基础打造专业网站?
如何快速上传自定义模板至建站之星?
东莞市网站制作公司有哪些,东莞找工作用什么网站好?
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
Laravel怎么上传文件_Laravel图片上传及存储配置
Win11怎样安装网易有道词典_Win11安装词典教程【步骤】
Laravel与Inertia.js怎么结合_使用Laravel和Inertia构建现代单页应用
用yum安装MySQLdb模块的步骤方法
Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel怎么导出Excel文件_Laravel Excel插件使用教程
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制
宙斯浏览器怎么屏蔽图片浏览 节省手机流量使用设置方法
如何用景安虚拟主机手机版绑定域名建站?
Laravel策略(Policy)如何控制权限_Laravel Gates与Policies实现用户授权
ai格式如何转html_将AI设计稿转换为HTML页面流程【页面】
香港服务器网站卡顿?如何解决网络延迟与负载问题?
Laravel如何处理CORS跨域问题_Laravel项目CORS配置与解决方案
JS经典正则表达式笔试题汇总
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
Laravel定时任务怎么设置_Laravel Crontab调度器配置
Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】
高防服务器如何保障网站安全无虞?
lovemo网页版地址 lovemo官网手机登录
Laravel如何处理和验证JSON类型的数据库字段
如何在不使用负向后查找的情况下匹配特定条件前的换行符
Laravel如何使用Vite进行前端资源打包?(配置示例)
Win11怎么设置默认图片查看器_Windows11照片应用关联设置
如何在万网利用已有域名快速建站?
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
如何注册花生壳免费域名并搭建个人网站?
独立制作一个网站多少钱,建立网站需要花多少钱?
制作公司内部网站有哪些,内网如何建网站?
Laravel如何使用Livewire构建动态组件?(入门代码)
html文件怎么打开证书错误_https协议的html打开提示不安全【指南】
中山网站推广排名,中山信息港登录入口?
Android自定义listview布局实现上拉加载下拉刷新功能
Laravel如何升级到最新版本?(升级指南和步骤)
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
如何在宝塔面板创建新站点?
JS中对数组元素进行增删改移的方法总结
Laravel路由怎么定义_Laravel核心路由系统完全入门指南
如何确保FTP站点访问权限与数据传输安全?
南京网站制作费用,南京远驱官方网站?
免费视频制作网站,更新又快又好的免费电影网站?
Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程
Laravel Session怎么存储_Laravel Session驱动配置详解
香港服务器如何优化才能显著提升网站加载速度?


