美文网首页
JS 原始类型的方法

JS 原始类型的方法

作者: 弹指一挥间_e5a3 | 来源:发表于2020-10-13 09:26 被阅读0次
    let str = "Hello";
    
    alert( str.toUpperCase() ); // HELLO
    

    以下是 str.toUpperCase() 中实际发生的情况:

    1. 字符串 str 是一个原始值。因此,在访问其属性时,会创建一个包含字符串字面值的特殊对象,并且具有有用的方法,例如 toUpperCase()
    2. 该方法运行并返回一个新的字符串(由 alert 显示)。
    3. 特殊对象被销毁,只留下原始值 str

    所以原始类型可以提供方法,但它们依然是轻量级的。

    JavaScript 引擎高度优化了这个过程。它甚至可能跳过创建额外的对象。但是它仍然必须遵守规范,并且表现得好像它创建了一样。

    数字有其自己的方法,例如,toFixed(n) 将数字舍入到给定的精度:

    let n = 1.23456;
    
    alert( n.toFixed(2) ); // 1.23
    

    面试题

    var str = 'string';
    str.pro = 'hello';
    console.log(str.pro + 'world'); //undefinedworld
    

    这个问题先放一边,我们回到标题中的问题:

    var str = 'string';
    console.log(str.length); // 6
    

    str 变量并没有 length 属性,不是说好了只有对象才能用 . 或者 [] 去访问属性值吗? 这里我们要引入一个叫做 基本包装类型 的概念。除了 Object Array 等引用类型外,其实还有三种特殊的引用类型 String Number 和 Boolean,方便我们操作与其对应的基本类型,而它们就是基本包装类型。str 作为一个基本类型是没有 length 属性的,但是它的基本包装类型 String 有啊,其实在执行 console.log(str.length) 这段代码时,事情的经过是这样的:

    1. 创建String类型的一个实例
    2. 在实例上调用指定的方法
    3. 销毁这个实例

    所以获取字符串变量 str 的长度的代码,内部实现大概是这个样子的:

    var str = 'string';
    var len = str.length;
    console.log(len); // 6
    
    var str = 'string';
    var _str = new String(str);
    var len = _str.length;
    _str = null;
    console.log(len); // 6
    

    那么我们再回到面试题,也就不难理解了。当执行 str.pro = 'hello' 时,实际上内部创建了一个基本包装类型的实例,然后给这个实例的 pro 属性赋值为 hello ,实例创建后马上销毁了,当下一次试图获取 str.pro 的值时,又会创建一个基本包装类型的实例,显然新创建的实例时没有 pro 属性的,为 undefined ,所以最后输出 undefinedworld
    最后引用一段《Javascript启示录》中的话:

    在针对字符串、数字和布尔值使用字面量时,只有在该值被视为对象的情况下才会创建实际的复杂对象。换句话说,在尝试使用与构造函数关联的方法或检索属性(如var len = 'abc'.length) 之前,一直在使用原始数据类型。当这种情况发生时,Javascript 会在幕后为字面量值创建一个包装器对象,以便将该值视为一个对象。调用方法以后,Javascript 即抛弃包装器对象,该值返回字面量类型。这就是字符串、数字、布尔值被认为是原始数据类型的原因。

    相关文章

      网友评论

          本文标题:JS 原始类型的方法

          本文链接:https://www.haomeiwen.com/subject/ytnmpktx.html