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 个步骤:
- 创建函数模板。
- 在函数模板中,拿到函数原型,并赋值。
- 在函数模板中,拿到函数实例,并赋值。
- 返回构造函数。
- 返回构造函数实例。