#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()
?
PHP中文网2017-04-17 11:13:09
Well, actually the answer lies in the source code V8.h, starting from line 1720.
/**
* A JavaScript function object (ECMA-262, 15.3).
*/
class Function : public Object {
public:
V8EXPORT Local<Object> NewInstance() const;
V8EXPORT Local<Object> NewInstance(int argc, Handle<Value> argv[]) const;
V8EXPORT Local<Value> Call(Handle<Object> recv,
int argc,
Handle<Value> argv[]);
V8EXPORT void SetName(Handle<String> name);
V8EXPORT Handle<Value> GetName() const;
};
Then the interface of V8::Function::Call
is consistent with the [[Call]]
in definition 15.3 of ECMA-262.
Note that the definition of [[Call]]
(15.3.4.5.1) and the definition of Function.prototype.call
(15.3.4.4) are completely different . [[Call]]
is an internal method that needs to be called during the implementation of Function.prototype.call
(and almost all other Function.prototype
defined in ECMA-262).
When the [[Call]] internal method of a function object, F
, which was created using the bind function is called with a this
value and a list of arguments ExtraArgs
, 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 list boundArgs
in the same order followed by the same values as the list ExtraArgs
in the same order.target
providing boundThis
as the this
value and providing args
as the arguments.So the first parameter is the execution context, which is used to determine this
when the code is executed.
Then the source code provided by LZ actually just passes the global scope as this into Call. The function is to call itself (cb in the context) in the global scope.