莫名多出个_locals属性
req.body
今天使用express做一个图书管理项目练习时,发现对req.body得到的数据,进行遍历赋值的时候,莫名多出来一个_locals属性,值是一个空对象。通过console.log将req.body打印出来却又没有这一项。
使用 hasOwnProperty 进行判断,结果抛出异常 xxx.hasOwnProperty is not a function,打印其原型__proto__
,得到的却是undefined,一系列事情实在令人费解。
// 修改图书信息
exports.editBook = (req, res) => {
let book = req.body;
// console.log(book);
// console.log(book.__proto__);
for(let i = 0; i < data.length; i++){
if(data[i].bookId == book.bookId){
for(let k in book){
// if(book.hasOwnProperty(k))
// console.log(k,book[k])
data[i][k] = book[k];
}
break;
};
}
writeDataToFile(res);
}
想尽各种方法,就是找不到_locals这个属性在哪。
虽然想出了一个解决办法,但是却是避开了遍历req.body数据,而用另一个期望数据来代替的方法。
// 修改图书信息
exports.editBook = (req, res) => {
let book = req.body;
for(let i = 0; i < data.length; i++){
if(data[i].bookId == book.bookId){
for(let k in data[i]){ // 遍历data[i]而不是book中的键
data[i][k] = book[k];
}
break;
};
}
writeDataToFile(res);
}
这样确实是解决了会多出一个_locals属性的问题,但是还是没解决我的疑惑,这个_locals属性到底是怎么来的?
网上找到了一个可以在chrome浏览器中调试node的方法,使用node-inspector来实现浏览器端调试node。
【技巧】断点调试你的express项目
然后在调试过程中终于发现了,原来不是req.body中有_locals属性,而是不知道什么原因,在data对应的那个数据中添加了_locals属性。
由此又引起了我的疑惑:
- 这个_locals是哪来的?
还是之前没解决的问题,只是从原来的目标req.body变成了data - 为什么会刚好只有对应修改的数据有_locals这个属性?
如果能了解到第一个问题的答案,也许这个问题也能解决吧。 - 为什么改成遍历data[i],结果数据中就不再有_locals这个属性了呢?
原本以为这个属性是req.body加上的,自然是没有这个疑问,但是既然这个属性是在data[i]里面,那么用遍历data[i]得到的键名k,通过book(req.body)给data[i]的属性赋值,应该是不会清除掉data[i]._locals这一项的才对。
data中的_locals
带着疑惑,把代码修改一下后再次调试查看一下。
// 修改图书信息
exports.editBook = (req, res) => {
let book = req.body;
for(let i = 0; i < data.length; i++){
if(data[i].bookId == book.bookId){
for(let k in data[i]){ // 遍历data[i]而不是book中的键
data[i][k] = book[k];
}
break;
};
}
writeDataToFile(res);
}
可以看到依然是刚进入方法对应要修改的data数据就有了_locals属性。
进入循环之后可以发现,遍历data[i]的时候确实有一个_locals被遍历出来了,只是因为book对象中没有该属性,所以data[i][‘_locals’]被重新赋值为undefined。
但是至此data数据中还是应该存在着_locas这个属性才对,
事实上,也确实是,在执行完毕editBook方法之后,确实显示_locals属性还是存在的,为什么在最后的文件中却没有出现这一项,我只能猜测是之后在其他一些依赖或框架的某个方法将这个undefined的值给清除掉了。
问题还是没有解决
最终问题还是没有彻底解决,没有完全搞明白,暂时先放一下吧,也不知道以后能不能弄清楚了。
问题的原因
data 数据原本是通过require(‘./data.json’)引入的,修改代码成为文件读取得到数据的形式,发现不会出现 _locals属性了。
let data = fs.readFileSync(path.join(__dirname, 'data.json'));
data = JSON.parse(data);
之前调试的时候,会直接在修改的数据中添加一项 _locals属性,而现在修改了获取数据的方式之后,很明显的看到,莫名多出来的_locals属性不见了。
这里做一个猜测:require()是用来引入其他模块的,一般都是一个js文件,提供一个接口对象或方法,而在data.json文件中并没有这样的接口,是直接的json数据,所以不应该使用require()来引入。