为什么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) 这段代码时,事情的经过是这样的:
- 创建String类型的一个实例
- 在实例上调用指定的方法
- 销毁这个实例
所以获取字符串变量 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 即抛弃包装器对象,该值返回字面量类型。这就是字符串、数字、布尔值被认为是原始数据类型的原因。
为什么Javascript中的基本类型能调用方法?的更多相关文章
- JavaScript中判断对象类型的种种方法
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
- 转 JavaScript中判断对象类型的种种方法
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
- JavaScript中判断对象类型方法大全1
我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...
- JavaScript中判断变量类型最简洁的实现方法以及自动类型转换(#################################)
这篇文章主要介绍了JavaScript中判断整字类型最简洁的实现方法,本文给出多个判断整数的方法,最后总结出一个最短.最简洁的实现方法,需要的朋友可以参考下 我们知道JavaScript提供了type ...
- C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法
使用反射(Reflect)获取dll文件中的类型并调用方法 需引用:System.Reflection; 1. 使用反射(Reflect)获取dll文件中的类型并调用方法(入门案例) static v ...
- JavaScript中两种类型的全局对象/函数【转】
Snandy Stop, thinking is the essence of progress. JavaScript中两种类型的全局对象/函数 这里所说的JavaScript指浏览器环境中的包括宿 ...
- XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)
XML序列化 #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...
- javaScript中Number数字类型方法入门
前言 Number和Math都属于JavaScript中的内置对象,Number数字类型作为基础数据类型,我们在开发过程中会经常用到,包括数字精度的格式化,还有字符串转换成数字等操作. Number数 ...
- jquery ajax中支持哪些返回类型以及js中判断一个类型常用的方法?
1 jquery ajax中支持哪些返回类型在JQuery中,AJAX有三种实现方式:$.ajax() , $.post , $.get(). 预期服务器返回的数据类型.如果不指定,jQuery 将自 ...
随机推荐
- IO系统性能之一:衡量性能的几个指标
作为一个数据库管理员,关注系统的性能是日常最重要的工作之一,而在所关注的各方面的性能只能IO性能却是最令人头痛的一块,面对着各种生涩的参数和令人眼花缭乱的新奇的术语,再加上存储厂商的忽悠,总是让我们有 ...
- shell执行mysql命令
难点主要在参数的传递方式吧,不过查资料后发现很简单. 1.使用-e参数传递命令,适用于简单语句 mysql -uuser -ppasswd -e "create database ...
- (转)android.intent.action.MAIN与android.intent.category.LAUNCHER
android.intent.action.MAIN决定应用程序最先启动的Activity android.intent.category.LAUNCHER决定应用程序是否显示在程序列表里 在网上看到 ...
- Centos和Redhat的区别和联系
网上看到的,转载给大家 CentOS与RedHat的关系: RedHat在发行的时候,有两种方式:二进制的发行方式以及源代码的发行方式.无论是哪一种发行方式,你都可以免费获得(例如从网上下载),并再次 ...
- 禁止Visual Studio启动时自动连接TFS服务器
在默认设置情况下,Visual Studio启动时,会自动连接上次打开过的TFS服务器.这种设计能够提高开发人员的工作效率,避免每次手动连接TFS服务器. 但是在某些情景中,也会给人造成不必要的麻烦, ...
- UVa 297 Quadtrees -SilverN
A quadtree is a representation format used to encode images. The fundamental idea behind the quadtre ...
- 【CImg】霍夫变换——直线检测
霍夫变换——直线检测 考古debug,其实很久之前就解决的bug......一直忘记过来改文章....欸 =============================原文================ ...
- NOIP水题合集[3/未完待续]
NOIP2008pj传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球, ...
- 第26章 创建型模式大PK
26.1 工厂方法模式 VS 建造者模式 26.1.1 按工厂方法建造超人 (1)产品:两类超人,成年超人和未成年超人. (2)工厂:这里选择简单工厂 [编程实验]工厂方法建造超人 //创建型模式大P ...
- 使用while循环语句和变量输出九九乘法表
输出的结果如下: