为什么字符串类型可以调用构造函数String的方法,却又不是它的实例

从所周知,在 JS中定义一个字符串我们有两种办法:

	var a = new String("a");
	 
	var a = "a";

  第一种方法使用构造函数创建,作为 String 的实例,自然可以使用 String 原型的方法,这个我们不讨论。

  第二种方式,给变量 a 赋值一个原始类型 string,它也可以使用 String 原型的方法,甚至也包含 __proto__ 这个属性,那么看来原始类型 string 也是一个对象,也是 String 的实例咯?然而事实是这样吗?

  我们通过简单的几行代码测试一下:

		console.log(a.__proto__ === String.prototype) //true

  首先是a的原型指向了String的原型,OK这个挺符合预期的。

		console.log(a.constructor === String) //true

  然后a的constructor属性指向了构造函数String,这个也是自然,毕竟constructor就是从String.prototype继承来的。

		console.log(a instanceof String); //false

  什么?为什么 instanceof 判断却说 a 不是 String 的实例或者说是原型链的一环,instanceof 不就是沿着原型链去找吗,连 a.__proto__ === String.prototype 都成立了啊!

不卖关子了,其实我们所见并非所得:

  在读取字符串的时候会创建一个对象,但是这个对象只是临时的,所以我们称它为临时对象,学术名字叫包装对象,说它临时,是因为我们在读取它的属性的时候,js会把这个string字符串通过new String()方式创建一个字符串对象,一旦引用结束,这个对象就被销毁了。

  原来如此,怪不得会出现这么诡异的现象,为了验证上面这句话的正确性,我们可以尝试给a添加一个属性,如果a是一个实例对象,那么a的属性是可以修改的。

		a.b = "b";
		
		console.log(a.b)  //undefined

  证明了a不是一个对象。其他的原始类型如Number、boolean也并不是一个对象,它们都是通过包装对象来调用构造函数上的方法的。

最后引用《JavaScript权威指南》里面的一句话补充一下:

  其实(包装对象)在实现上并不一定创建或销毁这个临时对象,然而整个过程看起来是这样的。


转载自 “GuJinYu” 的博文 为什么字符串类型可以调用构造函数String的方法,却又不是它的实例

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值