看视频学习js过程中经常看到js中通过基础数据类型调用方法,就很纳闷,不是说好基本数据类型和引用数据类型不一样的吗,只有对象才能调用方法的嘛,咋基础数据类型能调,比如定义一个number类型数据,var num=123,然后通过num.toString()直接转换成String类型。
有疑问问百度。。终于找到满意的答案。以下内容转载自为什么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
有了这个包装器对象的概念,操作数字字符串就方便多了!