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

JavaScript中Object.create与new关键字的区别及proto变量undefined问题

嘿,这个问题问到点子上了——很多刚摸透JavaScript原型链的开发者都会在这里踩坑。我分两部分给你讲清楚:

一、Object.create() 和 new 关键字的核心区别

这俩都是用来创建对象的,但底层逻辑和使用场景差得挺多:

1. 执行流程完全不同

  • new Constructor() 背后偷偷做了四件事:

    • 先创建一个空的新对象
    • 把这个新对象的__proto__绑定到构造函数的prototype属性上
    • 调用构造函数,把this指向这个新对象(所以构造函数里的this.xxx会直接挂在新对象身上)
    • 如果构造函数没返回引用类型(比如对象、数组),就返回这个新对象;否则返回构造函数自己返回的那个对象
  • Object.create(proto, [props]) 就简单多了:它直接以你传入的proto对象作为新对象的__proto__来创建对象,完全不会执行任何构造函数。第二个可选参数是用来给新对象添加自身属性的,格式和Object.defineProperties()一致。

2. 原型指向的灵活性不一样

  • 用new的话,你只能间接指定原型——新对象的__proto__固定指向构造函数的prototype,除非你先改构造函数的prototype,不然没法直接把任意对象当原型。
  • Object.create() 就灵活多了:你可以传入任何对象(甚至null,这时新对象没有原型,连toString这种基础方法都没有)作为新对象的原型。比如Object.create(null)常用来做干净的字典,不用担心和Object.prototype上的方法重名。

3. 对象自身属性的来源不同

  • new出来的对象,自身属性主要来自构造函数里通过this绑定的内容;原型链上的属性才来自构造函数的prototype。
  • Object.create()创建的对象,自身属性要么是第二个参数定义的,要么是后续手动加的;原型链上的属性全来自你传入的proto对象。
二、为什么原型中的变量有时能输出、有时返回undefined?

我猜你大概率是搞混了原型指向的对象——先看两个典型的对比例子:

例子1:用new能正常访问原型变量

function Animal() {}
Animal.prototype.sound = "woof";

const dog1 = new Animal();
console.log(dog1.sound); // 输出 "woof"

原因很简单:dog1的__proto__指向Animal.prototype,当访问dog1.sound时,dog1自己没有这个属性,就会沿着原型链往上找,刚好在Animal.prototype上找到,所以能输出。

例子2:错误使用Object.create导致undefined

const dog2 = Object.create(Animal); // 注意这里传的是构造函数Animal,不是Animal.prototype
console.log(dog2.sound); // 输出 undefined

这里的问题在于:dog2的__proto__指向的是Animal这个函数本身,而不是Animal.prototype。Animal函数的原型链是Animal → Function.prototype → Object.prototype,根本碰不到Animal.prototype上的sound属性,自然返回undefined。

例子3:正确使用Object.create就能正常访问

const dog3 = Object.create(Animal.prototype);
console.log(dog3.sound); // 输出 "woof"

这时候dog3的__proto__和new Animal()出来的dog1完全一致,原型链能找到Animal.prototype上的sound,所以正常输出。

还有一种少见但容易踩的坑:如果构造函数返回了一个引用类型的值,new会直接返回这个值,而不是它创建的新对象,这时候新对象的原型链就和构造函数的prototype没关系了:

function Person() {
  return { name: "Charlie" }; // 返回一个对象
}
Person.prototype.age = 25;

const p = new Person();
console.log(p.age); // undefined —— 因为p是构造函数返回的对象,它的__proto__不是Person.prototype

总结一下:当你觉得“两种写法的原型都有某个变量”时,大概率是原型指向的对象搞错了——new绑定的是构造函数的prototype,而Object.create需要你明确传入这个prototype对象,才能和new的原型链一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:48:09