深入浅出的理解 谷歌浏览器 V8 引擎 -- 隐藏类


谷歌浏览器 V8 引擎有一个概念 叫做隐藏类。它的作用就是加快访问对象的属性

1. C++ 快速的访问成员变量

   我们知道C++是编译型语言,在编译期间,对象大小(size)和 成员变量 相对于对象地址的偏移量也确定了 。那么在运行期间,想要访问某个成员,根据首地址和偏移量计算出 成员的地址。即 对象首地址(object address) + 成员地址的偏移量( member offset) = 成员变量的地址(member address),有了成员的地址就能快速访问成员了。

先来看看下面的C++代码,就能更好的理解了:(不熟悉C++也没事,代码里面的每行都有注释,很简单)

#include <iostream>

/*新建一个测试类,包含两个成员变量*/
class TestClass {
	public:
	    int attr;	//定义成员1
		int attr2;  //定义成员2
   TestClass(int val) : attr(val) {}
};
 
int main() {

	TestClass obj(10);  //定义TestClass类型的对象
	
	// 对象的大小
	std::cout << "对象的大小: " << sizeof obj <<std::endl;
	
	// 输出 对象的地址
	std::cout << "对象地址: " << &obj << std::endl;
	 
    //输出 成员1属性的地址
    std::cout << "成员(属性)1的地址: " << &obj.attr  << std::endl;

	//输出 成员2属性的地址
	std::cout << "成员(属性)2的地址: " << &obj.attr2  << std::endl;
	getchar();
  return 0;
}

运行结果:
在这里插入图片描述
   上面的例子看到对象的大小(size)是 8个字节。为什么是 8 个字节?因为它只包含两个整型,一个整型的大小为 4 字节。我们还看到对象的地址和成员1的地址是一致的都为 0x0075F8C8。上面运行期间是如何快速获得成员的地址的 ?得益于编译期间的就确定的成员偏移表。下面看看 TestClass 成员的偏移表 和 对象成员的地址关系:
在这里插入图片描述

C++ 为什么要建立这个偏移表,通过计算获得成员地址呢 ?直接在运行的时候设置成员变量表岂不是更快?

答:上面的例子中,使用 TestClass 只定义了一个对象,那如果在程序中我们定义了5个、10个、100个对象呢,那岂不是要记录每个对象成员的地址,那么庞大的地址表,岂不是糟糕透顶了。


2. 隐藏类

   C++是编译型语言可以做到事先编译,JavaScript是解释性语言,它自身不会事先编译,就没法事先建立类似的偏移表。这个时候,谷歌的 V8 解决了这个,V8 实现 JIT(即时)编译器将JavaScript 代码 编译成机器代码。V8 提出了一个 隐藏类 的概念,实现和 C++ 中的成员偏移表相似的 功能。
V8在运行时 Javascript 创建对象时 ,同时在其内部也会创建隐藏类,程序员不用去关心这个隐藏类。使用相同的构建函数创建多个对象时 可以使用同一个隐藏类。这样就大大的提高了 访问对象成员的效率。来看一下下面的代码:

function Article() {
	this.title = 'javaScript 内存管理';
}
let a1 = new Article();
let a2 = new Article();

   这里的 对象a1、a2 就是通过Article() 这个构造函数创建的,它们就可以共享同一个隐藏类。

小结

V8 引擎是开源的,现在很多浏览器都是使用这个引擎,我们学习隐藏类还是非常有必要的。

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值