You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript对象创建差异解析及无效实例原因(结合原型机制)

JavaScript对象创建差异与原型深度解析

先把你给出的代码贴出来方便对照:

var a = {x:1}; 
var b = function(y){this.x = y}; 
var c = new Object({x:1}); 
var d = new b(1); 
var e = b(1); 
var f = (y) => {return {x:y};}; 
var g = new f(1); // error 
var h = f(1); 
var i = new a();//error 

咱们逐个拆解这些变量,结合JS原型链的核心知识,搞明白它们的区别,还有为啥g和i会报错。


1. var a = {x:1};

这是最常用的对象字面量创建方式,属于语法糖,底层和new Object()逻辑类似,但更高效。

  • a是一个普通对象,它的原型链顶端是Object.prototype(也就是a.__proto__ === Object.prototype为true)。
  • 注意:a是对象,不是函数,所以不能用new调用它——这就是后面new a()报错的原因。

2. var b = function(y){this.x = y};

这是一个普通构造函数(本质就是普通函数,只是约定俗成用大写开头,不过这里用了小写b也不影响功能)。

  • 作为函数,它的原型是Function.prototype;同时它自带一个prototype属性,指向一个默认对象(这个对象的constructor属性会指向b自己)。
  • 当用new调用它时,会生成一个绑定了b.prototype的新实例。

3. var c = new Object({x:1});

这是通过Object构造函数创建对象的方式,和a几乎没有本质区别:

  • c的原型同样是Object.prototype,c.x的值也是1。
  • 唯一的区别是创建方式:对象字面量是语法糖,写起来更简洁,性能也略优,日常开发里优先用字面量而不是new Object()。

4. var d = new b(1);

这是正确调用构造函数的方式,生成了b的实例:

  • 执行new b(1)时,JS引擎会先创建一个空对象,把这个对象的__proto__绑定到b.prototype,然后把this指向这个新对象,执行函数体里的this.x = y(也就是把d.x设为1),最后返回这个新对象。
  • 所以d.__proto__ === b.prototype为true,d是b的实例。

5. var e = b(1);

这里直接调用了函数b,没有用new,和构造调用完全是两回事:

  • 在非严格模式下,函数里的this会指向全局对象(浏览器里是window,Node.js里是global),所以执行后全局对象会多一个x属性,值为1;严格模式下this是undefined,这时候会报错Cannot set property 'x' of undefined。
  • 因为函数b没有显式return任何值,所以e的结果是undefined。

6. var f = (y) => {return {x:y};};

这是一个箭头函数,它和普通函数有几个核心差异:

  • 没有自己的this,它的this是继承自外层作用域的;
  • 没有prototype属性——这是关键,也是后面new f(1)报错的核心原因;
  • 不能被当作构造函数使用。

7. var g = new f(1); // error

报错的原因很明确:箭头函数不能作为构造函数。

  • new操作符的工作流程依赖构造函数的prototype属性:它需要把新创建的对象的__proto__绑定到构造函数的prototype上,但箭头函数根本没有prototype,所以JS引擎会直接抛出TypeError: f is not a constructor的错误。

8. var h = f(1);

直接调用箭头函数f是完全没问题的:

  • 箭头函数执行后返回一个对象字面量{x:1},所以h就是这个对象,它的原型是Object.prototype,和a、c本质上是一样的。

9. var i = new a();//error

报错原因:a是普通对象,不是函数,而new操作符要求后面必须是一个构造函数(也就是函数类型的值)。

  • 普通对象没有prototype属性,也无法完成new操作的绑定原型、绑定this等步骤,所以会抛出TypeError: a is not a constructor的错误。

核心总结

  • 只有函数(普通函数、生成器函数等)才能被当作构造函数用new调用,普通对象不行;
  • 箭头函数因为没有prototype属性,不能作为构造函数使用;
  • new调用构造函数会生成绑定了构造函数prototype的新实例,而直接调用函数的this指向全局(非严格模式)或undefined(严格模式);
  • 对象字面量、new Object()创建的对象,原型都是Object.prototype;构造函数new出来的实例,原型是构造函数的prototype。

内容的提问来源于stack exchange,提问作者ShAkKiR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:49:23