Js 代码在执行时,会被 V8 引擎解析,这时 V8 会用不同的模板来处理 Js 中的对象和函数。例如:
- ObjectTemplate 用来创建对象
- FunctionTemplate 用来创建函数
- PrototypeTemplate 用来创建函数原型
V8 中的定义得到以下结论:
- Js 中的函数都是 FunctionTemplate 创建出来的,返回值的是 FunctionTemplate 实例。
- Js 中的对象都是 ObjectTemplate 创建出来的,返回值的是 ObjectTemplate 实例。
- Js 中函数的原型(prototype)都是通过 PrototypeTemplate 创建出来的,返回值是 ObjectTemplate 实例。
所以 Js 中的对象的原型可以这样判断:
- 所有的对象的原型都是 Object.prototype,自定义构造函数的实例除外。
- 自定义构造函数的实例,它的原型是对应的构造函数原型。
在 Js 中的函数原型判断就更加简单了。
- 所有的函数原型,都是 Function.prototype。
下图展示了所有的内置构造函数,他们的原型都是 Function.prototype。
看到这里,你是否也可以一看就看出任何对象的原型呢?
附:V8 中的函数解析案例
了解完原型链之后,我们看一下 V8 中的函数解析。
function Student(name) {this.name = name;}Student.prototype.study = function () {console.log("study js");};const student = new Student('xiaoming')
这段代码在 V8 中会这样执行:
// 创建一个函数v8::Local<v8::FunctionTemplate> Student = v8::FunctionTemplate::New();// 获取函数原型v8::Local<v8::Template> proto_Student = Student->PrototypeTemplate();// 设置原型上的方法proto_Student->Set("study", v8::FunctionTemplate::New(InvokeCallback));// 获取函数实例v8::Local<v8::ObjectTemplate> instance_Student = Student->InstanceTemplate();// 设置实例的属性instance_Student->Set("name", String::New('xiaoming'));// 返回构造函数v8::Local<v8::Function> function = Student->GetFunction();// 返回构造函数实例v8::Local<v8::Object> instance = function->NewInstance();
以上代码可以分为 4 个步骤:
- 创建函数模板。
- 在函数模板中,拿到函数原型,并赋值。
- 在函数模板中,拿到函数实例,并赋值。
- 返回构造函数。
- 返回构造函数实例。
