Я следующий код, написанный для NodeJS:Странное поведение массива в NodeJS
/* server.js */
'use strict';
const http = require('http'),
url = require('url');
METHODS = ['GET','POST','PUT','DELETE'],
_routePathIndex = Array.apply(null, Array(METHODS.length)).map(() => {return []}),
_routeMethodIndex = _routePathIndex.slice(),
_server = http.createServer();
_server.on('request', (req, res) => {
let parsed = url.parse(req.url),
methodIndexVal = METHODS.indexOf(req.method),
PathIndexVal = _routePathIndex[methodIndexVal].indexOf(parsed.pathname);
_routeMethodIndex[methodIndexVal][PathIndexVal](req, res);
});
module.exports = _init();
function _init(){
let rs = { listen: _listen };
METHODS.forEach((val,i) => {
rs[val.toLowerCase()] = function(route, handler){
_routePathIndex[i].push(route);
_routeMethodIndex[i].push(handler);
};
});
return rs;
};
function _listen(port, callback){
_server.listen(port, callback);
}
Чтобы проверить это у меня есть у меня есть очень простой скрипт:
/* server.test.js */
var app = require('./server.js');
app.get('/', (req,res) => { console.log(req, res); });
app.listen(3000,() => { console.log('listening at port', 3000) });
Странность начинается на линии 2 server.test.js, который выполняет следующий код в server.js, я добавил комментарии для отображения значений как _routePathIndex
, так и _routeMethodIndex
.
...
rs[val.toLowerCase()] = function(route, handler){
/* _routePathIndex: [ [], [], [], [], ]
_routeMethodIndex: [ [], [], [], [], ] */
_routePathIndex[i].push(route);
/* _routePathIndex: [ ['/'], [], [], [], ]
_routeMethodIndex: [ ['/'], [], [], [], ] */
_routeMethodIndex[i].push(handler);
/* _routePathIndex: [ ['/', [Function]], [], [], [], ]
_routeMethodIndex: [ ['/', [Function]], [], [], [], ] */
};
...
Мой вопрос, почему массив действует как Тхо привязаны друг к другу?
Сначала я подумал, может быть это был .slice()
, который делает ссылку, но я развенчан, что, выполнив следующий сценарий в той же среде:
var a = [], b = a.slice();
a.push(1);
console.log(a,b); // [1] [0]
Другое дело, когда я не делаю .slice()
трюк и переработан код в качестве такого
...
_routePathIndex = Array.apply(null, Array(METHODS.length)).map(() => {return []}),
_routeMethodIndex = Array.apply(null, Array(METHODS.length)).map(() => {return []}),
странное поведение реферирование закончится и код работает отлично!
Дополнительная информация Я работаю с node -v
: v5.4.1
.
Также я попытался клонировать массив, используя [].concat(_routePathIndex)
но он все еще имел, что странное поведение
'Array.apply (NULL, Array (METHODS.length)) карту (() = > {return []}) 'кажется (мне) запутанным и нечитаемым способом записи' Array (METHODS.length) .fill ([]) ' – jcaron