Do you really know the object

原始类型的方法
JavaScript 允许我们像使用对象一样使用原始类型(字符串,数字等)。JavaScript 还提供了这样的调用方法。我们很快就会学习它们,但是首先我们将了解它的工作原理,毕竟原始类型不是对象(在这里我们会分析地更加清楚)。

我们来看看原始类型和对象之间的关键区别。

一个原始值:

是原始类型中的一种值。
在 JavaScript 中有 7 种原始类型:string,number,bigint,boolean,symbol,null 和 undefined。
一个对象:

能够存储多个值作为属性。
可以使用大括号 {} 创建对象,例如:{name: “John”, age: 30}。JavaScript 中还有其他种类的对象,例如函数就是对象。
关于对象的最好的事儿之一是,我们可以把一个函数作为对象的属性存储到对象中。

let john = {
name: “John”,
sayHi: function() {
alert(“Hi buddy!”);
}
};

john.sayHi(); // Hi buddy!

所以我们在这里创建了一个包含 sayHi 方法的对象 john。

许多内建对象已经存在,例如那些处理日期、错误、HTML 元素等的内建对象。它们具有不同的属性和方法。

但是,这些特性(feature)都是有成本的!

对象比原始类型“更重”。它们需要额外的资源来支持运作。

当作对象的原始类型
以下是 JavaScript 创建者面临的悖论:

人们可能想对诸如字符串或数字之类的原始类型执行很多操作。最好将它们作为方法来访问。
原始类型必须尽可能的简单轻量。
而解决方案看起来多少有点尴尬,如下:

原始类型仍然是原始的。与预期相同,提供单个值
JavaScript 允许访问字符串,数字,布尔值和 symbol 的方法和属性。
为了使它们起作用,创建了提供额外功能的特殊“对象包装器”,使用后即被销毁。
“对象包装器”对于每种原始类型都是不同的,它们被称为 String、Number、Boolean 和 Symbol。因此,它们提供了不同的方法。

例如,字符串方法 str.toUpperCase() 返回一个大写化处理的字符串。

用法演示如下:

let str = “Hello”;

alert( str.toUpperCase() ); // HELLO

尝试运行下面代码

let str = “Hello”;

str.test = 5;

alert(str.test);

根据你是否开启了严格模式 use strict,会得到如下结果:

undefined(非严格模式)
报错(严格模式)。
为什么?让我们看看在 (*) 那一行到底发生了什么:

当访问 str 的属性时,一个“对象包装器”被创建了。
在严格模式下,向其写入内容会报错。
否则,将继续执行带有属性的操作,该对象将获得 test 属性,但是此后,“对象包装器”将消失,因此在最后一行,str 并没有该属性的踪迹。
这个例子清楚地表明,原始类型不是对象。

它们不能存储额外的数据。

js 对象是应用类型

let fruits = [“Apples”, “Pear”, “Orange”];

// 在“副本”里 push 了一个新的值
let shoppingCart = fruits;
shoppingCart.push(“Banana”);

// fruits 里面是什么?
alert( fruits.length ); // ?

let fruits = [“Apples”, “Pear”, “Orange”];

let shoppingCart = fruits;

shoppingCart.push(“Banana”);

alert( fruits.length ); // 4
这是因为数组是对象。所以 shoppingCart 和 fruits 是同一数组的引用。