#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...)