写JavaScript的时候,创建对象几乎是每天都在做的事。最常见的两种写法一种是var obj = {},另一种是var obj = new Object()。两者产出的对象看起来一模一样,都能挂属性、都能遍历,于是不少人会觉得这只是风格差异,用哪个都行。但深入到语言规范层面,这两种写法其实有不少值得推敲的差别,包括语法解析机制、作用域安全问题以及潜在的隐式转换坑。

语法层面:字面量是声明式,构造函数是函数调用
对象字面量{}是JavaScript语言内置的声明式语法,解析器在语法分析阶段就知道这里要创建一个对象,直接生成创建对象的指令。而new Object()本质上是一次函数调用加上new运算符的组合,涉及查找Object这个标识符、以构造函数形式执行等一系列运行时步骤。
这种差别最直接的体现是初始化属性的方式。字面量允许在创建的同时就把属性写好,代码紧凑且意图清晰:
var user = {
name: '张三',
age: 25,
sayHi: function () {
console.log('你好,我是' + this.name);
}
};如果换成new Object(),则需要先创建空对象再逐个赋值:
var user = new Object();
user.name = '张三';
user.age = 25;
user.sayHi = function () {
console.log('你好,我是' + this.name);
};后者不仅代码更长,而且属性添加分散在多条语句中,可读性明显下降。当代码需要review或者排查问题时,一段集中的对象定义显然比散落各处的赋值语句更容易把握全貌。这也是主流代码规范如Airbnb风格指南明确要求只使用字面量创建对象的重要原因。
作用域隐患:Object标识符可能被覆盖
new Object()的另一个问题是它依赖全局作用域里的Object标识符。JavaScript允许在局部作用域重新声明同名变量,一旦发生遮蔽,行为就可能出乎意料:
function demo() {
var Object = function () {
this.name = '被覆盖了';
};
var obj = new Object(); // 实际调用的是局部构造函数
console.log(obj.name); // 输出:被覆盖了
}虽然很少有人会故意这么写,但在维护老旧代码或引入第三方脚本时,这类标识符冲突并非天方夜谭。而对象字面量{}是纯语法结构,不经过任何标识符查找,天然免疫这种作用域遮蔽问题。
类似的隐患还出现在其他内置构造函数上,比如String、Number、Boolean被局部覆盖后,对应的字面量写法依然稳定可靠。这也是为什么有经验的开发者普遍遵循一条原则:能用字面量就不要碰构造函数。
隐式转换的坑:Object作为普通函数调用
还有一个容易被忽视的细节:Object不加new直接调用时是一个类型转换函数,它会根据传入参数返回不同类型的值,而不是总返回对象:
console.log(Object('hello')); // 返回String包装对象
console.log(Object(42)); // 返回Number包装对象
console.log(Object(true)); // 返回Boolean包装对象
console.log(Object(null)); // 返回普通空对象
console.log(new Object('hello')); // 同样返回String包装对象
var a = new Object('hello');
console.log(a instanceof String); // true,不是预期的普通对象可以看到,如果向new Object()传入一个原始值,得到的是对应的包装对象而非普通对象。包装对象在松散相等比较时表现诡异,new Object(false) == false结果是true,但在严格相等下又是false,调试起来非常折磨人。对象字面量则始终创建一个干净的、原型指向Object.prototype的普通对象,行为完全可预期。
更危险的是Object()在不带new的情况下,如果传入的是某个对象就直接原样返回。这意味着某些依赖类型判断的逻辑可能被一个意外的构造函数调用破坏掉,而这类bug往往只在特定输入下才触发,定位成本很高。
性能与规范建议
从执行性能角度看,现代JavaScript引擎对字面量的优化程度远高于构造函数调用。以V8为例,字面量会在解析阶段被识别并生成固定的初始化模板,配合隐藏类机制,属性布局可以被引擎精确预测;而new Object()走的是通用的构造调用路径,后续逐条赋值语句会让隐藏类多次迁移,增加了优化难度。虽然单次差异在毫秒以下,但在高频创建对象的热点代码里,累积差距不容忽视。
综合来看,两者的选择其实没有太多悬念。日常开发中优先使用对象字面量,它语法简洁、结构集中、不依赖全局标识符、行为可预期,并且对引擎优化更友好。new Object()几乎没有任何字面量做不到的独门能力,保留它主要是历史兼容和语言完整性的需要。类似的结论也适用于数组:[]优于new Array(),字符串、数字、布尔值同理。理解这背后的原理,不只是记住一条编码规范,而是真正明白声明式语法与运行时函数调用在语言设计上的本质区别,这种思维方式迁移到其他语言特性上同样有价值。
对象字面量JavaScript对象new Object修改时间:2026-09-16 11:18:30