On this page
MongoDB 2.4 中的 JavaScript 更改
在本页面
考虑V8 JavaScript 引擎在 MongoDB 2.4 中的以下影响:
Tip
在mongo shell 中使用新的interpreterVersion()
方法,在db.serverBuildInfo()的输出中使用javascriptEngine字段,以确定 MongoDB 二进制文件使用哪个 JavaScript 引擎。
Improved Concurrency
以前,需要 JavaScript 解释器的 MongoDB 操作必须获得一个锁,并且一个mongod一次只能运行一个 JavaScript 操作。切换到 V8 通过允许同时运行多个 JavaScript 操作来提高并发性。
现代化的 JavaScript 实现(ES5)
ECMAscript的第五版(缩写为 ES5)增加了许多新的语言功能,包括:
standardized JSON,
array extensions, and
吸气剂和二传手。
使用 V8,MongoDB 支持 Javascript 的 ES5 实现,但以下情况除外。
Note
以下功能在 从 MongoDB 查询返回的文档 中无法正常工作:
Object.seal()
从 MongoDB 查询返回的文档上引发异常。Object.freeze()
从 MongoDB 查询返回的文档上引发异常。Object.preventExtensions()
错误地允许在从 MongoDB 查询返回的文档中添加新属性。enumerable
属性,当添加到 MongoDB 查询返回的文档中时,在写操作期间不会保存。
有关更多信息,请参见SERVER-8216,SERVER-8223,SERVER-8215和SERVER-8214。
对于尚未从 MongoDB 查询返回的对象,这些功能将按预期工作。
删除了非标准 SpiderMonkey 功能
V8 不支持以下非标准的SpiderMonkey JavaScript 扩展,以前由 MongoDB 使用 SpiderMonkey 作为其 JavaScript 引擎来支持。
E4X Extensions
V8 不支持非标准 E4Xextensions。 E4X 为 JavaScript 语言提供了本机XML对象,并添加了将 LiteralsXML 文档嵌入 JavaScript 代码中的语法。
如果使用以下任何构造函数/方法,则需要使用替代 XML 处理:
XML()
Namespace()
QName()
XMLList()
isXMLName()
Destructuring Assignment
V8 不支持非标准的销毁分配。解构分配“使用镜像数组和对象常量的语法从数组或对象中提取数据”。 -Mozilla docs
Example
以下解构分配对于 V8 来说是“无效”的,并抛出SyntaxError
:
original = [4, 8, 15];
var [b, ,c] = a; // <== destructuring assignment
print(b) // 4
print(c) // 15
Iterator(),StopIteration()和 Generators
V8 不支持Iterator(),StopIteration()和生成器。
InternalError()
V8 不支持InternalError()
。请改用Error()
。
每个...在构造中
V8 不支持使用for each…in构造。请改用for (var x in y)
构造。
Example
以下for each (var x in y)
构造对于 V8 是**无效的:
var o = { name: 'MongoDB', version: 2.4 };
for each (var value in o) {
print(value);
}
相反,在版本 2.4 中,可以使用for (var x in y)
构造:
var o = { name: 'MongoDB', version: 2.4 };
for (var prop in o) {
var value = o[prop];
print(value);
}
您还可以将数组* instance *方法forEach()
与 ES5 方法Object.keys()
结合使用:
Object.keys(o).forEach(function (key) {
var value = o[key];
print(value);
});
Array Comprehension
V8 不支持Array comprehensions。
使用其他方法,例如Array
实例方法map()
,filter()
或forEach()
。
Example
对于 V8,以下数组推导是 无效的 :
var a = { w: 1, x: 2, y: 3, z: 4 }
var arr = [i * i for each (i in a) if (i > 2)]
printjson(arr)
相反,您可以使用Array
* instance *方法forEach()
和 ES5 方法Object.keys()
来实现:
var a = { w: 1, x: 2, y: 3, z: 4 }
var arr = [];
Object.keys(a).forEach(function (key) {
var val = a[key];
if (val > 2) arr.push(val * val);
})
printjson(arr)
Note
新逻辑使用Array
* instance 方法forEach()
而不是 generic *方法Array.forEach()
; V8 不支持Array
通用方法。有关更多信息,请参见数组通用方法。
多个捕获块
V8 不支持多个catch
块,将抛出SyntaxError
。
Example
以下多个 catch 块在 V8 上是“无效”的,将抛出"SyntaxError: Unexpected token if"
:
try {
something()
} catch (err if err instanceof SomeError) {
print('some error')
} catch (err) {
print('standard error')
}
条件函数定义
V8 会产生与 SpiderMonkey 条件函数定义不同的结果。
Example
以下条件函数定义在 SpiderMonkey 与 V8 中产生不同的结果:
function test () {
if (false) {
function go () {};
}
print(typeof go)
}
对于 SpiderMonkey,条件函数输出undefined
,而对于 V8,条件函数输出function
。
如果您的代码以这种方式定义函数,则强烈建议您重构代码。以下示例重构了条件函数定义,使其可同时在 SpiderMonkey 和 V8 中使用。
function test () {
var go;
if (false) {
go = function () {}
}
print(typeof go)
}
重构的代码在 SpiderMonkey 和 V8 中都输出undefined
。
Note
ECMAscript 禁止条件函数定义。强制 V8 抛出Error
,启用严格模式。
function test () {
'use strict';
if (false) {
function go () {}
}
}
JavaScript 代码引发以下语法错误:
SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.
字符串通用方法
V8 不支持String generics。字符串泛型是String
类上反映实例方法的一组方法。
Example
通用方法String.toLowerCase()
的以下用法在 V8 中“无效”:
var name = 'MongoDB';
var lower = String.toLowerCase(name);
在 V8 中,请使用String
类的* instance *可用的String
实例方法toLowerCase()
:
var name = 'MongoDB';
var lower = name.toLowerCase();
print(name + ' becomes ' + lower);
在 V8 中,请使用String
* instance 方法而不是以下 generic *方法:
String.charAt() |
String.quote() |
String.toLocaleLowerCase() |
String.charCodeAt() |
String.replace() |
String.toLocaleUpperCase() |
String.concat() |
String.search() |
String.toLowerCase() |
String.endsWith() |
String.slice() |
String.toUpperCase() |
String.indexOf() |
String.split() |
String.trim() |
String.lastIndexOf() |
String.startsWith() |
String.trimLeft() |
String.localeCompare() |
String.substr() |
String.trimRight() |
String.match() |
String.substring() |
数组通用方法
V8 不支持数组通用方法。数组泛型是Array
类上反映实例方法的一组方法。
Example
通用方法Array.every()
的以下用法在 V8 中“无效”:
var arr = [4, 8, 15, 16, 23, 42];
function isEven (val) {
return 0 === val % 2;
}
var allEven = Array.every(arr, isEven);
print(allEven);
在 V8 中,请使用Array
类的* instance *可用的Array
实例方法every()
:
var allEven = arr.every(isEven);
print(allEven);
在 V8 中,请使用Array
* instance 方法而不是以下 generic *方法:
Array.concat() |
Array.lastIndexOf() |
Array.slice() |
Array.every() |
Array.map() |
Array.some() |
Array.filter() |
Array.pop() |
Array.sort() |
Array.forEach() |
Array.push() |
Array.splice() |
Array.indexOf() |
Array.reverse() |
Array.unshift() |
Array.join() |
Array.shift() |
数组实例方法 toSource()
V8 不支持Array
实例方法toSource()。请改用Array
实例方法toString()
。
uneval()
V8 不支持非标准方法uneval()
。请改用标准化的JSON.stringify()方法。