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

为何两段JavaScript原型相关代码运行结果不同?

问题分析与解答

先看你提供的两段代码:

第一段可运行代码

var Class = new MyClass(); 
function MyClass() {} 
var Class1 = new MyClass(); 
function Class1() {} 
console.log(Class1.prototype == Class.prototype); 
MyClass.prototype.sayName = function() { alert("abc"); }; 
Class.sayName(); 

第二段报错代码

function sayName() { alert("abc"); } 
MyClass.prototype.sayName(); 
Class.sayName(); 

为什么第二段代码会报错?

你提到系统提示sayName未定义,但核心问题其实和函数提升无关,主要出在这两点:

  1. MyClass完全没被声明
    这段代码里根本没有定义MyClass构造函数——既没有函数声明,也没有变量赋值。JS引擎执行MyClass.prototype时,会直接抛出ReferenceError: MyClass is not defined(如果你的环境提示sayName未定义,大概率是代码中断前的误导,或是存在笔误)。就算跳过这个问题,还有第二个关键问题:

  2. 全局sayName和MyClass.prototype.sayName是完全独立的标识符
    你声明的function sayName()是挂载在全局作用域的函数,但MyClass.prototype.sayName是访问MyClass原型对象上的属性——两者没有任何关联。函数提升只会让全局的sayName提前可用,但不会自动把它绑定到MyClass的原型上。

再看第一段代码能运行的原因

第一段代码正常工作,是因为:

  • 函数声明function MyClass()会被提升到作用域顶端,所以执行var Class = new MyClass()时,MyClass已经存在;
  • 后续代码给MyClass.prototype添加了sayName方法,而Class是MyClass的实例,它的原型链指向MyClass.prototype,所以Class.sayName()能找到并调用这个方法。

如何修复第二段代码?

如果想让第二段代码运行,你需要:

  • 先声明MyClass构造函数;
  • 把全局的sayName函数绑定到MyClass的原型上,或者直接调用全局函数:
// 先声明构造函数
function MyClass() {}
// 把全局函数赋值给原型
function sayName() { alert("abc"); }
MyClass.prototype.sayName = sayName;

// 创建实例后调用方法
var Class = new MyClass();
Class.sayName(); // 能正常弹出abc

如果只是想调用全局的sayName,直接写sayName()即可,不需要通过MyClass.prototype。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:20:39