为什么字符串‘abc‘可以调用length属性?

为什么字符串’abc’可以调用length属性?字符串’abc’本身不是一个对象,为什么可以用点.运算符来调用length?

由字面量定义的字符串在使用其length属性时其实做了如下的操作

1、 创建了一个 String 类型的实例
2、使用实例的属性或方法
3、销毁实例

 const str = 'abc'
    console.log(str.length);
    // 在执行 str.length 的时候 做了以下三步
    // 1. let str = new String('abc')
    // 2. console.log(str.length);
    // 3. str = null

这里引用一个概念包装对象

包装对象

包装对象指的是与数值、字符串、布尔值分别相对应的Number、String、Boolean三个原生对象,在一定条件下,原始数据类型也会自动转为对象,所以万物皆对象。

	var v1 = new Number(123);
	var v2 = new String('abc');
	var v3 = new Boolean(true);

	typeof v1 // "object"
	typeof v2 // "object"
	typeof v3 // "object"

	v1 === 123 // false
	v2 === 'abc' // false
	v3 === true // false
   

这个又要与Number(value),String(str),Boolean(value)几个方法区分开来,不加new运算符的时候,是将括号内的值转换为对应的原始类型值,如:

// 字符串转为数值
Number('111') // 111

// 数值转为字符串
String(111) // "111"

// 数值转为布尔值
Boolean(111) // true

所以什么情况下原始类型值会自动转换为包装对象,调用包装对象上的方法呢?

'abc'.length // 3

这种场合就会自动转,JavaScript 引擎在这种情况下会自动将其转为包装对象,在这个对象上调用length属性。调用结束后,这个临时对象就会被销毁。这就叫原始类型与实例对象的自动转换。 上述代码就相当于

var str = 'abc'
var strObj = new String(str)
// String {
//   0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"
// }
strObj.length // 3,直接调用自身的属性`length`,调用完立马销毁。

最后

所以总结就是,字符串或者数字,可以调用某种方法或属性,js引擎会默认转换为对应的包装类型,用包装类型上面的方法或属性。而非调用原型链上的方法和属性。

你可能感兴趣的:(javascript,前端,原型模式)