Express报错:Cannot access 'playlist' before initialization 问题求助
解决Express音乐播放器/playlist接口的ReferenceError问题
你开发的基于Express的音乐播放器,目前能正常上传文件到./mp3目录并写入playlist.json,但调用/playlist接口时触发错误:ReferenceError: Cannot access 'playlist' before initialization。
原错误代码
const express = require('express'); const upload = require("express-fileupload"); const editJsonFile = require("edit-json-file"); const fs = require('fs'); const app = express(); app.use(upload()) app.use(express.urlencoded({ extended: true })) const playlist = editJsonFile(`${__dirname}/playlist.json`); app.post("/upload", (req, res) => { //Save file from the html form to ./mp3 var file = req.files.file; req.pipe(fs.createWriteStream("./mp3/" + file.name)); res.send("File uploaded"); playlist.append("playlist", file.name) playlist.save() }), app.get("/playlist", (req, res) => { console.log(playlist.get("playlist")) let playlist = playlist.get("playlist") let html = ""; for (let i = 0; i < playlist.length; i++) { html += `<br>${playlist[i]}`; } res.send(html); }),
错误原因
在/playlist的GET路由处理函数中,你用let playlist声明了一个局部变量,这个变量名和全局作用域的playlist(即editJsonFile返回的实例)重名了。根据JavaScript的变量提升规则,let声明的变量会被提升到作用域顶部,但处于“暂时性死区”,在赋值语句let playlist = ...之前访问这个变量就会触发错误——这里你在赋值前就试图调用playlist.get("playlist"),实际访问的是局部的playlist而非全局的那个。
修复方案
把局部变量的名字改成和全局变量不冲突的名称,比如playlistItems:
const express = require('express'); const upload = require("express-fileupload"); const editJsonFile = require("edit-json-file"); const fs = require('fs'); const app = express(); app.use(upload()) app.use(express.urlencoded({ extended: true })) const playlist = editJsonFile(`${__dirname}/playlist.json`); app.post("/upload", (req, res) => { var file = req.files.file; req.pipe(fs.createWriteStream("./mp3/" + file.name)); res.send("File uploaded"); playlist.append("playlist", file.name) playlist.save() }), app.get("/playlist", (req, res) => { console.log(playlist.get("playlist")) // 修改局部变量名,避免和全局playlist冲突 let playlistItems = playlist.get("playlist") let html = ""; for (let i = 0; i < playlistItems.length; i++) { html += `<br>${playlistItems[i]}`; } res.send(html); }),
这样修改后,路由里访问的playlist.get("playlist")会正确指向全局的playlist实例,局部变量playlistItems存储获取到的播放列表数据,循环时也使用这个局部变量,就不会再触发错误了。
内容的提问来源于stack exchange,提问作者spjdev
相关产品推荐
相关产品推荐

