/*! * Module dependencies. */ 'use strict'; const CoreMongooseArray = require('./core_array'); const arrayAtomicsSymbol = require('../helpers/symbols').arrayAtomicsSymbol; const arrayParentSymbol = require('../helpers/symbols').arrayParentSymbol; const arrayPathSymbol = require('../helpers/symbols').arrayPathSymbol; const arraySchemaSymbol = require('../helpers/symbols').arraySchemaSymbol; const _basePush = Array.prototype.push; /** * Mongoose Array constructor. * * ####NOTE: * * _Values always have to be passed to the constructor to initialize, otherwise `MongooseArray#push` will mark the array as modified._ * * @param {Array} values * @param {String} path * @param {Document} doc parent document * @api private * @inherits Array * @see http://bit.ly/f6CnZU */ function MongooseArray(values, path, doc, schematype) { let arr; if (Array.isArray(values)) { const len = values.length; // Perf optimizations for small arrays: much faster to use `...` than `for` + `push`, // but large arrays may cause stack overflows. And for arrays of length 0/1, just // modifying the array is faster. Seems small, but adds up when you have a document // with thousands of nested arrays. if (len === 0) { arr = new CoreMongooseArray(); } else if (len === 1) { arr = new CoreMongooseArray(1); arr[0] = values[0]; } else if (len < 10000) { arr = new CoreMongooseArray(); _basePush.apply(arr, values); } else { arr = new CoreMongooseArray(); for (let i = 0; i < len; ++i) { _basePush.call(arr, values[i]); } } if (values[arrayAtomicsSymbol] != null) { arr[arrayAtomicsSymbol] = values[arrayAtomicsSymbol]; } } else { arr = new CoreMongooseArray(); } arr[arrayPathSymbol] = path; // Because doc comes from the context of another function, doc === global // can happen if there was a null somewhere up the chain (see #3020) // RB Jun 17, 2015 updated to check for presence of expected paths instead // to make more proof against unusual node environments if (doc != null && doc.$__ != null) { arr[arrayParentSymbol] = doc; arr[arraySchemaSymbol] = schematype || doc.schema.path(path); } return arr; } /*! * Module exports. */ module.exports = exports = MongooseArray;