干货 | 快速读懂 JS 原型链
OSC开源社区 昨天
以下文章来源于前端日志 ,作者前端日志
理解原型链 深入原型链 总结与思考
理解原型链
原型(prototype) 链( __proto__
)
原型(prototype)
function Student(name) { this.name = name; this.study = function () { console.log("study js"); };}// 创建 2 个实例const student1 = new Student("xiaoming");const student2 = new Student("xiaohong");student1.study();student2.study();
function Student(name) { this.name = name;}Student.prototype.study = function () { console.log("study js");};// 创建 2 个实例const student1 = new Student("xiaoming");const student2 = new Student("xiaohong");student1.study();student2.study();
为什么 student1 能够访问到 Student 原型上的属性和方法?
__proto__
中,我们接着往下看。链(__proto__
)
__proto__
)可以理解为一个指针,它是实例对象中的一个属性,指向了构造函数的原型(prototype)。function Student(name) { this.name = name;}Student.prototype.study = function () { console.log("study js");};
const student = new Student("xiaoming");student.study(); // study jsconsole.log(student.__proto__ === Student.prototype); // true
__proto__
指向了构造函数的 prototype,上文中遗留的问题也就解决了。为什么调用 student.study 时,访问到的却是 Student.prototype.study 呢?
原型链
function Student(name) { this.name = name;}Student.prototype.study = function () { console.log("study js");};
const student = new Student("xiaoming");student.study(); // study js。// 在实例中没找到,在构造函数的原型上找到了。// 实际调用的是:student.__proto__.say 也就是 Student.prototype.say。
student.toString(); // "[object Object]"// 在实例中没找到。// 在构造函数的原型上也没找到。// 在构造函数的原型的原型上找到了。// 实际调用的是 student.__proto__.__proto__.toString 也就是 Object.prototype.toString。
__proto__
就像一个链一样,串联起了实例对象和原型。为什么 Student.prototype.__proto__
是 Object.prototype?
先找 __proto__
前面的对象,也就是 Student.prototype 的构造函数。判断 Student.prototype 类型, typeof Student.prototype
是object
。object
的构造函数是 Object。得出 Student.prototype 的构造函数是 Object。 所以 Student.prototype.__proto__
是 Object.prototype。
原型链常见问题
Function.__proto__
是什么?
找 Function 的构造函数。 判断 Function 类型, typeof Function
是function
。函数类型的构造函数就是 Function。 得出 Function 的构造函数是 Function。 所以 Function.__proto__
= Function.prototype。
Number.__proto__
是什么?
找 Number 的构造函数。 判断 Number 类型, typeof Number
是function
。函数类型的构造函数就是 Function。 得出 Number 的构造函数是 Function。 所以 Number.__proto__
= Function.prototype。
Object.prototype.__proto__
是什么?
Object.prototype.__proto__
是 Object.prototype,但这是不对的,这样下去原型链就在 Object 处无限循环了。Object.prototype.__proto__
为 null,打破了原型链的无线循环。深入原型链
V8 是怎么创建对象的
ObjectTemplate 用来创建对象 FunctionTemplate 用来创建函数 PrototypeTemplate 用来创建函数原型
Js 中的函数都是 FunctionTemplate 创建出来的,返回值的是 FunctionTemplate 实例。 Js 中的对象都是 ObjectTemplate 创建出来的,返回值的是 ObjectTemplate 实例。 Js 中函数的原型(prototype)都是通过 PrototypeTemplate 创建出来的,返回值是 ObjectTemplate 实例。
所有的对象的原型都是 Object.prototype,自定义构造函数的实例除外。 自定义构造函数的实例,它的原型是对应的构造函数原型。
所有的函数原型,都是 Function.prototype。
附: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();
创建函数模板。 在函数模板中,拿到函数原型,并赋值。 在函数模板中,拿到函数实例,并赋值。 返回构造函数。 返回构造函数实例。
总结与思考
不看的原因确定内容质量低不看此公众号
赞 (0)