【知识梳理】基本类型的自动装箱?

336 阅读2分钟

起因

众所周知,基本类型如 var str = 'hello'; 中的 str 可以调用所有的 String 对象方法。

很多文章把这种行为解释为自动装箱机制,类似以下工作流程:

var str = 'hello';

var index = str.indexOf('h');
// 相当于
var temp = new String(str);
var index = temp.indexOf('h');
temp = null;

这固然是种非常容易理解的模式,但是如果在同一上下文中,每调用一次方法,就去创建一个 String 对象,是否性能过差,浏览器是否真如上面所说的这样进行工作的呢,以 chrome 为例(不同内核浏览器表现的有差异),我开始了探索。

探索

劫持 new String

最开始,我想通过一种方式,看看浏览器在执行字符串方法时,是否真的 new 了一个 String 对象。通过探索我找到下面这种方式,

var bind = Function.bind;
var unbind = bind.bind(bind);

function instantiate(constructor, args) {
    return new (unbind(constructor, null).apply(null, args));
}

String = function (String) {
    MyString.prototype = String.prototype;

    return MyString;

    function MyString() {
        console.log('new String');
        var str = instantiate(String, arguments);
        return str;
    }
}(String);

var copyFunc = String.prototype.indexOf;
String.prototype.indexOf = function (s) { console.log('My indexOf', this.valueOf(), arguments); return copyFunc.call(this.valueOf(), s); }

var a = '123';
console.log(a.indexOf('1'));
console.log(a.indexOf('2'));

Chrome 执行后发现,我们在使用 indexOf 方法时,并没有 new String 。但是 String 原型链上的 indexOf 确实被调用了,说明 v8 可以不创建一个完整的 String 对象下直接使用字符串的方法。

其他资料

带着想了解 v8 此处机制的目的,我找到了一些资料,来自 javascript.infoStackOverflow.

javascript.info 中介绍基本类型的文章中提到。

image.png

而在 StackOverflow 中的介绍更加的清晰,这位老哥回答到,这非常依赖引擎的实现,他尝试以 v8 为例,解释一下工作原理。一个基本类型的字符串在 v8 中会被解析为 v8::String ,方法可以被直接调用。

image.png

总结

这个小知识从 MDN 复习到原始数据时,看到一句基本类型是既非对象也无方法的数据,引发思考的。

image.png

通过资料的查证和学习,对这块的了解也变得更加清晰了,对 v8 的实现也觉得没有那么神秘了,^_^ !