#define BUILDING_NODE_EXTENSION
#include <node.h>
using namespace v8;
Handle<Value> RunCallback(const Arguments& args) {
HandleScope scope;
Local<Function> cb = Local<Function>::Cast(args[0]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
cb->Call(Context::GetCurrent()->Global(), argc, argv);
return scope.Close(Undefined());
}
void Init(Handle<Object> exports, Handle<Object> module) {
module->Set(String::NewSymbol("exports"),
FunctionTemplate::New(RunCallback)->GetFunction());
}
NODE_MODULE(addon, Init)
主要是第十二行 cb->Call(Context::GetCurrent()->Global(), argc, argv);
。
原代码在这里,然后文档里面是这么写的:
V8EXPORT Local
v8::Function::Call ( Handle< Object > recv, int argc, Handle< Value > argv[] )
第一个参数是 Handle<Object> recv
。
求问这个参数是干吗用的?什么意思?它调用的时候为什么要用 Context::GetCurrent()->Global()
?
唔,其實答案還是在源碼V8.h裏,1720行起。
那麼
V8::Function::Call
的接口和ECMA-262裏的定義15.3裏的[[Call]]
是一致的。注意,
[[Call]]
(15.3.4.5.1)的定義和Function.prototype.call
(15.3.4.4)的定義完全不一樣的。[[Call]]
是Function.prototype.call
(及其他幾乎所有ECMA-262中定義的Function.prototype
)的實現過程中需要調用的內部方法。15.3.4.5.1 [[Call]]
When the [[Call]] internal method of a function object,
F
, which was created using the bind function is called with athis
value and a list of argumentsExtraArgs
, the following steps are taken:boundArgs
be the value of F’s [[BoundArgs]] internal property.boundThis
be the value of F’s [[BoundThis]] internal property.target
be the value of F’s [[TargetFunction]] internal property.args
be a new list containing the same values as the listboundArgs
in the same order followed by the same values as the listExtraArgs
in the same order.target
providingboundThis
as thethis
value and providingargs
as the arguments.所以第一個參數就是執行上下文,用於確定代碼執行時的
this
。然後LZ給的源碼,其實就是把全局作用域當做this傳進了Call而已,作用是在全局作用域裏麵調用自身(上下文中的cb)。
加入 javascript, function.call(this,arg...)