原文地址:https://strongloop.com/strongblog/node-js-v0-12-c-apis-breaking/
编者注:欢迎阅读旨在帮你快速了解,在即将发布的node0.12中( 作者写这篇文章的时候Node0.12还没有发布,译者注 )的API变化三系列教程的第三部分。在第一部分,Alex Gorbatchev列出来没有变化的API,在第二部分中他指出了变化的部分。在第三部分,Ben Noordhuis将会详细描述C++API部分的差别。
在Node v0.10和v0.12之间有大量的差异。我不会试图把每一个细节都点出来,我将把这些差异分类,按照从“更重要”到“次重要”的次序进行排序,然后解释怎样合理的更新你的代码。
本文大部分讲述V8 API,因为这正是大量差异出现的地方。欢迎通过ben at strongloop.com来给我提供建议和反馈。
原生函数的参数已经被更改
在node v0.10中你这么写:
在node v0.12中你这么写:
一些重要的变化如下:
- 返回类型是
void
。
- 返回值通过
v8::ReturnValue::Set()
,v8::ReturnValue::SetEmptyString()
,v8::ReturnValue::SetNull()
,v8::ReturnValue::SetUndefined()
来设置。
- 如果没有显式的设置返回值,将会返回
undefined
。
v8::ReturnValue::Set()
拥有一个数字类型的重载函数可以是使用不同的数据类型。如果你的编译器处理时出现问题或者报歧义错误,那么就是使用static_cast<>
来将参数转为支持的类型:
当然你需要挑选合适的类型来转换。当转化为窄数据类型,以至于无法承载原始数据据时,将会产生不可预期的结果。
注意,v8::FunctionCallbackInfo<v8::Value>
是对于v8::Arguments
的重命名和参数化(parameterized )。除了名字和额外的GetReturnValue()
函数,他们没有表面上的差别。
大部分V8 API现在需要使用v8::Isolate*
在Node v0.10中你这么写:
在Node v0.12中你这么写:
你可以通过若干的方法获取当前的v8::Isolate
的指针:
注意,V8团队已经指出,v8::Isolate::GetCurrent()
将会被逐步淘汰。如果你想编写向后兼容的代码,你最好显式的传递isolate参数。
V8 string函数现在需要显式声明编码
在Node v0.10中你这么写:
在Node v0.12中你这么写:
v8::String::NewFromTwoByte()
稍微有点命名的不合适,因为他并不是一个严格的双字节编码。他能够识别surrogate pairs【 链接:https://msdn.microsoft.com/en-us/library/windows/desktop/dd374069(v=vs.85).aspx 】, 所以它应该被称作UTF-16,而不是UCS-2。
去除了v8::String::NewSymbol()和v8::String::NewUndetectable()
在Node v0.10中你这么写:
在Node v0.12中你这么写:
去除了v8::String::AsciiValue
在Node v0.10中你这么写:
在Node v0.12中你这么写:
Nothing! v8::String::AsciiValue
本来就有问题:它的名字告诉大家要返回7比特的ASCII数据,但是实际上返回8比特的二进制数据。同时它搞混了多字节字符的字节序。
使用v8::String::Utf8Value
或者v8::String::Value
(适用于UTF-16)来进行替代。如果你想获取一个字符串的原始二进制数据,你可以这么做:
注意:v8::String::Utf8Length()
会迭代字符串中的每一个字符,这就是为啥对于大字符串来说会(很)慢的原因。
去除了v8::HandleScope::Close()
在Node v0.10中你这么写:
在Node v0.12中你这么写:
v8::Persistent不再继承自v8::Handle
v8::Persistent<T>
不再是v8::Handle<T>
类型的对象。这就意味着,你不能在直接访问指向的句柄了。做出如此大变革的动机是由于在v0.10中这么操作太容易导致资源泄露或者导致在释放之后再访问其存储的内容。
在Node v0.10中你这么写:
在Node v0.12中你这么写:
另外一个变化是,persistent 句柄现在不能被拷贝。在Node v0.10中你这么写:
在Node v0.12中你这么写:
由于v8::Persistent<T>
没有在语法上提供拷贝功能,所以现在使用STL容器类的时候会更困难。鉴于此,V8在v8-util.h
中提供了若干工具类。
举个例子:
如果你使用[C++](https://zh.wikipedia.org/wiki/CBB11 "%3")
,你可以在标准容器类的移动语义中使用v8::UniquePersistent<T>
。
或者,你可以通过具有拷贝特性的v8::Persistent<T>
,但是要保证这么做不会导致资源泄露或者在释放后再使用的问题:
弱引用persistent句柄的回调函数参数更改
一个正常的persistent句柄会被垃圾回收器忽略掉,一直到程序手动释放才会被回收。
相反,弱引用persistent句柄会被垃圾回收器跟踪,当需要回收时,回收器会通过回调函数通知程序。接着程序释放掉关联的资源或者复用这个句柄如果对象还要在后续使用的话。
在Node v0.10中这么写:
在Node v0.12中这么写:
v8::ThrowException()现在变成了 v8::Isolate::ThrowException()
在Node v0.10中这么写:
在Node v0.12中这么写: