0 前情提要
首先,回顾一下JavaScript的数据类型:
原始值: Number、String、Boolean、undefined
引用值: Object、function、数组
其中,引用值是可以有属性和方法的,如 obj.name = "xiaowus"
但是,原始值是不能有属性和方法的
字符串类型string,它比较特殊,它有一个属性叫 length
,这个属性的值是字符串的长度,如:
var str = "abcde";
console.log(str.length);
上面的代码输出结果为:5
既然前面说了,引用值是不能有属性和方法的,字符串类型也是引用值,那为什么字符串类型有length属性呢?
这时,就要引入一个新的概念——包装类
1 什么是包装类?
包装类其实就是系统自带的构造函数,一共有三个:
- Number()
- String()
- Boolean()
2 包装类如何使用及它有什么作用?
包装类如何使用?就跟构造函数的用法一样:
var num = new Number(123);
var str = new String('abc');
var bool = new Boolean(true);
console.log(num);
console.log(str);
console.log(bool);
输出结果为:
包装类有什么作用?
- 使用时,不是通过new来创建对象的话,可以用来类型转换,如:
var str = "123";
console.log(typeof(str)); //输出结果为string
var num = Number(str);
console.log(typeof(num)); //输出结果为number
- 使原始值变为包装类对象,使其可以添加属性和方法,如:
var num = 123;
var numObj = new Number(num);
numObj.name = "abc";
console.log(numObj.name); //输出结果为:abc
3 给原始值强行加上属性或方法会发生什么?
var num = 123;
num.length = 3; //原始值不能有属性或方法,但是这样写并不会报错
//系统会隐式地反生如下过程:
//系统隐式地创建一个包装类,把原始值作为参数传进去
//紧接着系统又会将它给删除了,实现了不报错,但又跟啥也没发生一样
//new Number(123).length = 3; delete;
console.log(num.length); //输出undefined
//当尝试访问那个属性时,系统又重新创建了一个包装类对象,然后实际访问的是包装类对象的属性
//但由于这个属性并不存在,所以访问的结果为undefined
4 字符串类型的length属性
字符串类型为什么可以有length属性,用包装类来解释就解释得通了
但为什么字符串类型的length属性可以存储字符串的长度呢?
因为 String()
这个包装类比较特殊,它天生自带一个length属性,就是用来存储字符串长度的
当访问字符串类型的length属性时,其实不是访问原始值字符串的length属性,而是包装类String的
var str = "abc";
str.length = 2; //并不会改变字符串的长度
//new String('abc').length = 2; delete
//就相当于啥也没发生一样
console.log(str.length); //输出的还是字符串原来的长度
//new String('abc').length
//所以访问字符串类型的length属性时,本质上访问的是包装类String的length属性