浏览器console里的双中括号 `[[ ]]`

双中括号 [[ ]] 在 JavaScript 里是什么意思?

你看到的 [[Prototype]]、[[Call]]、[[Get]] 这种写法,不是 JavaScript 语法,而是 ECMAScript 规范(标准文档)里用来描述"内部属性"或"内部方法"的符号。

简单说:这是写规范的人为了方便描述引擎内部行为而创造的一种标记,你不能在代码里直接写 obj.[[Prototype]],因为 JS 引擎不认识这种语法。


1. [[Prototype]] 到底指什么?

它就是每个对象内部的一个隐藏指针 ,指向它的原型对象。也就是你之前一直困惑的 __proto__ 或 Object.getPrototypeOf(obj) 所获取的东西。

在规范里,它叫 [[Prototype]]。而在实际代码中,你可以通过下面的方式访问:

js 复制代码
const obj = {};
// 现代推荐写法
console.log(Object.getPrototypeOf(obj)); // 等价于 obj.__proto__
// 老式(但几乎都支持)写法
console.log(obj.__proto__);
// 注意:__proto__ 不是规范强制要求,但所有主流引擎都实现了

所以 :[[Prototype]] 是规范里的抽象名词;__proto__ 和 Object.getPrototypeOf() 是你在代码里真正能用的东西。


2. 还有哪些常见的 [[ ]] 内部属性/方法?

内部名称 含义 对应代码中相关的部分
[[Prototype]] 对象的原型链接 __proto__ 或 Object.getPrototypeOf()
[[Get]] 访问属性时的内部操作 obj.prop 触发
[[Put]] 设置属性时的内部操作 obj.prop = value 触发
[[Call]] 函数被调用时的内部方法 func() 会触发,普通对象没有 [[Call]]
[[Construct]] 函数作为构造函数时的内部方法 new func() 会触发
[[HasInstance]] instanceof 运算符的内部判断 obj instanceof Func 会用到的
[[GetOwnProperty]] 获取自有属性的描述符 Object.getOwnPropertyDescriptor(obj, 'name')

这些你都不用记,你只需要知道:双中括号是"引擎内部"的东西,不是给你直接写在代码里的。


3. 为什么规范要用这种奇怪的符号?

因为规范需要区分"语言本身公开的属性"和"引擎内部为实现这些功能而必须有的隐藏槽位"。

  • 公开属性:Object.prototype、Function.prototype、obj.hasOwnProperty -- 你可以在代码里直接用。
  • 内部槽位:[[Prototype]]、[[Call]] -- 你不能用,但引擎的行为依赖于它们。

比如规范说:"当调用 obj.toString() 时,首先查找 obj 自身有没有 toString,如果没有,则沿着 [[Prototype]] 链查找。" 这里的 [[Prototype]] 就是指内部的原型链接。


4. 回到你最初的问题:[[Prototype]] 和 __proto__ 的关系

  • [[Prototype]] = 概念 / 内部槽位(规范层面)。
  • __proto__ = 一种历史遗留的访问器属性 ,它实际上读取和设置对象的 [[Prototype]]。

现代 JavaScript 推荐使用 Object.getPrototypeOf(obj) 来读,用 Object.setPrototypeOf(obj, proto) 来写,而不是直接用 __proto__(因为后者有性能隐患,且非标准)。


5. 一道题帮你巩固理解

js 复制代码
const arr = [];
// 请问 arr 的 [[Prototype]] 指向什么?
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true
console.log(Array.prototype.__proto__ === Object.prototype); // true

arr 的原型链是:
arr → Array.prototype → Object.prototype → null

这里的每个箭头,规范里就用 [[Prototype]] 来表示。


总结一句话 :双中括号是规范里的"内部暗号",不是代码。你看到 [[Prototype]] 时,就把它理解成"那个看不见但存在的原型指针"即可。

相关推荐
总要学点什么37 分钟前
第105篇:三维特效-流动图片墙体效果——让箭头沿墙长滚,它俩竟是同一份代码
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
Agent世界2 小时前
用 CDP 做发布自动化:四道机器闸门与产物验收
前端·javascript
FungLeo2 小时前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
总要学点什么2 小时前
第104篇:三维特效-流动墙体效果——让贴图沿墙流动,它却只肯走一条对角线
开发语言·javascript·ecmascript·gis·webgl·材质·cesium
某哈压力大2 小时前
SSH 突然 Connection reset?不是密钥坏了,是 OpenSSL 把 sshd 干趴了
前端·node.js·命令行
程序员大阳2 小时前
副队长ES6+教程(3)--解构赋值
前端·javascript·es6·赋值·解构
神膘护体小月半3 小时前
css - 元素背景图由 hover 触发,初次加载时闪动的解决办法
前端·javascript·css
程序员大阳3 小时前
副队长ES6+教程(2)--let 与 const
前端·javascript·es6·const·let·var
deli0073 小时前
写满 200GB 后 SSD 为什么掉到 95MB/s?SLC 缓存模型实测
前端
曦樂~4 小时前
【Web Development】03JavaScript 基础和事件
开发语言·前端·javascript