为何两段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未定义,但核心问题其实和函数提升无关,主要出在这两点:
MyClass完全没被声明
这段代码里根本没有定义MyClass构造函数——既没有函数声明,也没有变量赋值。JS引擎执行MyClass.prototype时,会直接抛出ReferenceError: MyClass is not defined(如果你的环境提示sayName未定义,大概率是代码中断前的误导,或是存在笔误)。就算跳过这个问题,还有第二个关键问题:全局
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
相关产品推荐
相关产品推荐

