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

技术问询:能否在constructor function内部声明prototype members?

在构造函数内部声明原型成员的可行性分析

问题背景

我看课程时发现讲师把原型成员写在构造函数外部,但这种写法有不少问题,想知道能不能把原型成员声明在构造函数内部——我试了下,功能好像正常。另外我查过很多网站,它们都是把原型成员写在外部的,我清楚这么折腾没实际优化意义,就是练手试试。

两种写法示例

外部声明原型成员的写法

function Stopwatch(){
   let running, stop, start;
}

Stopwatch.prototype.start = function(){
    if(running) throw new Error("This watch is already started! ");
    start = console.time("time")/1000;
    running = true;
}

Stopwatch.prototype.stop = function(){
    if(!running) throw new Error("The watch hasn't started yet!");
    stop = console.timeEnd("time")/1000;
    running = false;
}

const timer = new Stopwatch();

内部声明原型成员的写法

function Stopwatch(){
    let running, stop, start;
    
    Stopwatch.prototype.start = function(){
        if(running) throw new Error("This watch is already started! ");
        start = console.time("time")/1000;
        running = true;
    }
    
    Stopwatch.prototype.stop = function(){
        if(!running) throw new Error("The watch hasn't started yet!");
        stop = console.timeEnd("time")/1000;
        running = false;
    }
}
    
const timer = new Stopwatch();

解答

可以这么写,但存在两个关键问题:

  1. 重复赋值浪费性能:每实例化一次Stopwatch,就会重新给Stopwatch.prototype.start和stop赋值一次。原型方法的设计初衷是让所有实例共享同一份方法,这么写完全违背了这个设计,每次实例化都做重复操作,纯纯浪费资源。
  2. 变量作用域逻辑错误:原型方法里的running、start、stop是构造函数内部的局部变量,原型方法挂载在构造函数的prototype上,根本访问不到这些变量。你测试时觉得正常,只是因为只实例化了一次,闭包意外保留了变量,但如果实例化多个对象,所有实例会共享同一个running状态——比如第一个实例start后,第二个实例也会显示已启动,状态完全混乱。

网上都把原型成员写在外部,就是因为能避免这两个问题:只赋值一次,所有实例共享,而且原型方法可以通过this访问实例属性(如果把running等改成this.running的话)。

如果想保留私有变量的特性,正确的做法是把方法挂载在实例上(利用闭包),或者用ES6类的私有字段,而不是折腾原型方法的位置。

内容的提问来源于stack exchange,提问作者Lome G ner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:50:19