zoukankan      html  css  js  c++  java
  • 为什么Javascript中的基本类型能调用方法?

    我们从一道笔试题说起:

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

    输出啥?要理解这个问题,我们得从头说起。

    Javascript 数据类型分两大类,基本类型(或者说是原始类型)和引用类型。基本类型的值是保存在栈内存中的简单数据段,共有五种,按值访问,分别是 undefined null boolean number 和 string;而引用类型的值则是保存在堆内存中的对象,按引用访问,主要有 Object Array Function RegExp Date等。

    // 基本类型
    var a = 10;
    var b = true;
    var c = 'string';
    
    // 引用类型
    var d = {};
    var f = [];
    var e = new String('abc');
    

    我们再来回头看这道笔试题,很显然变量 str 是一个基本类型,str.pro 看上去是给 str 添加了一个属性,等等,我们似乎只有在当 str 是一个对象时才看到过这样的用法,似乎也已经习惯给对象添加 key-value 键值对,但是基本类型也行么?

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

    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 。而下面的代码也是一样的道理:

    var str = 1;
    str.pro = 2;
    console.log(str.pro + 10); // NaN
    

    有了这个包装器对象的概念,操作数字字符串就方便多了!

    最后引用一段《Javascript启示录》中的话:

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

  • 相关阅读:
    UIImageView添加圆角
    iOS开发之NSRunLoop的进一步理解
    OC与Swift混编
    源码:自己用Python写的iOS项目自动打包脚本
    iOS 自定义Tabbar实现push动画隐藏效果
    IOS开发基础篇--CAShapeLayer的strokeStart和strokeEnd属性
    Swift 之 函数与闭包的应用实例
    Facebook iOS App如何优化启动时间
    iOS 中的 Deferred Deep Linking(延迟深度链接)
    Cocos2d-x使用UserDefault数据持久化实例:保存背景音乐和音效设置
  • 原文地址:https://www.cnblogs.com/lessfish/p/4836101.html
Copyright © 2011-2022 走看看