JavaScript中有两种数据类型:基本数据类型(原始类型)和引用数据类型
JavaScript有7种基本数据类型,分别是:
String、Number、Boolean、Undefined、Null、Object以及ES6中新增的Symbol(本文不做讨论)
原始数据类型有没有属性和方法?
按照JavaScript数据类型的定义,只有引用数据类型(对象)才有属性和方法。,原始数据类型没有属性和方法。
接下来我们来看一个例子:
ini
let table = "桌子";
table.food = "苹果";
console.log("table的food属性是 " + table.food);
上面会输出什么呢?
上面table都设置了food属性等于苹果,那输出肯定是苹果啊
如果你看完题目第一反应就是上面的答案,那么恭喜你,答错了,输出是Undefined
因为原始数据类型没有属性和方法,只有引用数据类型(对象)才有属性和方法。
接下来再看一个例子
ini
let str = "我是原始值";
console.log(str.length);
我们调用length属性也可以打印出字符串的长度
字符串也不是对象,为什么能使用设置属性?为什么能使用length?而且不报错呢?
这是因为包装类对原始数据类型做了处理。
基本包装类型
JavaScript提供了三个特殊的引用类型,它们对应的构造函数是:
- String() :将基本数据类型字符串,转换为String对象。
- Number() :将基本数据类型的数字,转换为Number对象。
- Boolean() :将基本数据类型的布尔值,转换为Boolean对象。
通过上述的是三个包装类,可以将基本数据类型转换为对象
使用原始数据类型调用属性或方法时,会通过对应的包装类的构造函数转换为对象,然后使用对象调用继承的方法,调用完毕后,新创建的对象会销毁,原始数据类型仍是原始数据类型
用原始值调用属性或方法时时,系统会隐式的在后台完成以下动作:
1:创建一个对应类型的实例
2:在实例上调用指定的属性或方法
3:销毁这个实例
接下来看例子
例1
ini
let num = 4;
num.len = 2;
console.log(num.len); // => undefined
num.len = 2; => new Number(4).len = 2
相当于new了一个全新的对象,值为4,然后设置.len
执行完销毁实例
如果还调用,那么系统又会new Number(4).len
new出来的对象都不一样,所以对象访问一个没有的属性,返回undefined
例2
ini
let str = "abcd";
str.length = 2;
console.log(str); // => 'abcd'
console.log(str.length); // => 4
str.length = 2; => new String("abcd").length = 2;
相当于new了一个全新的对象,值为"abcd",然后设置length属性为2
执行完后销毁,再次调用方法和属性的话又相当于走了一遍new的过程
console.log(str.length);相当于new了一个全新的对象,值为"abcd",然后读取设置length属性为4
系统默认字符串有length,不过是对象字符串有
综合
看完上面两道例子,相信你已经对包装类有一定了解,接下来看下一个小例子
ini
let str = "我是原始数据类型";
let test = typeof str;
if (test.length === 6) {
test.msg = "String";
}
console.log(test.msg);
看看上面的代码会输出什么?
最终输出的结果是undefined
上述代码先是先声明了一个变量str,str里存着字符串"我是原始数据类型",然后typeof str会返回"String",String调用length属性会返回数字类型的6,所以if的条件成立,test给msg属性赋值,但是test是字符串,原始值赋值会通过包装类,相当于new一个String的实例,给这个实例的属性msg赋值为"String",然后销毁实例,最后console.log(test.msg)又new了一个实例,这个实例和上面的实例不是同一个人,所以没有这个msg属性,所以打印为undefined