大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。
我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。
最近我在写代码时,尝试用 new 调用一个箭头函数,结果直接报错了!
const createUser = () => {
this.name = "我"; // 箭头函数没有自己的 this
};
const user = new createUser(); // ❌ 报错:createUser is not a constructor
这让我很困惑:为什么普通函数可以用 new,箭头函数却不行? 今天就来彻底搞懂这个问题,顺便聊聊 this 的那些坑。
1. 箭头函数:JS 里的“叛逆小兵”
箭头函数(=>)是 ES6 引入的,它有两个特点:
- 没有自己的
this,而是继承外层作用域的this(词法作用域)。 - 不能用作构造函数,用
new调用会直接报错。
// 普通函数可以当构造函数
function Person(name) {
this.name = name;
}
const me = new Person("我"); // ✅ 正常
// 箭头函数不行
const Animal = (name) => {
this.name = name; // ❌ this 指向外层(比如 window)
};
const cat = new Animal("喵喵"); // ❌ 报错!
为什么这样设计?
因为箭头函数的 this 是固定的(绑定定义时的作用域),而构造函数需要动态 this(指向新创建的对象)。如果允许 new 箭头函数,this 的指向就乱套了。
2. 普通函数 vs 箭头函数:this 的战场
普通函数的 this:谁调用就指向谁
function showName() {
console.log(this.name);
}
const obj = { name: "我", showName };
obj.showName(); // "我"(this 指向 obj)
showName(); // undefined(严格模式)或 window(非严格模式)
箭头函数的 this:定义时就固定
const obj = {
name: "我",
showName: () => {
console.log(this.name); // this 指向外层(比如 window)
},
};
obj.showName(); // undefined(因为 this 不是 obj)
关键区别:
- 普通函数的
this是动态的(运行时决定)。 - 箭头函数的
this是静态的(定义时就固定)。
3. 为什么 new 不能用在箭头函数上?
new 关键字的底层逻辑:
- 创建一个新对象
{}。 - 让函数的
this指向这个新对象。 - 执行函数体。
- 如果函数没有
return,就返回this。
但箭头函数没有自己的 this!
如果强行 new 箭头函数:
const createUser = () => {
this.name = "我"; // this 是外层的(比如 window)
};
new createUser(); // ❌ 报错,因为无法绑定 this
JS 直接禁止这种操作,避免混乱。
4. 实际开发中的正确姿势
场景 1:需要动态 this(如构造函数)→ 用普通函数
function User(name) {
this.name = name;
}
const me = new User("我"); // ✅
场景 2:需要固定 this(如回调函数)→ 用箭头函数
const obj = {
names: ["我", "你", "他"],
printNames() {
this.names.forEach((name) => {
console.log(name); // ✅ this 正确指向 obj
});
},
};
obj.printNames();
5. 总结
-
箭头函数不能
new,因为它没有自己的this,无法绑定到新对象。 -
普通函数可以
new,因为它的this是动态的。 -
选择依据:
- 需要动态
this(如构造函数、方法)→ 普通函数。 - 需要固定
this(如回调、定时器)→ 箭头函数。
- 需要动态
下次再看到 new 和箭头函数的问题,你就能轻松应对了! 🚀