在 JavaScript 中,我们能为原始类型添加一个属性或方法吗?

简介: 在 JavaScript 中,我们能为原始类型添加一个属性或方法吗?

原始类型的方法


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


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


一个原始值:


  • 是原始类型中的一种值。
  • 在 JavaScript 中有 7 种原始类型:stringnumberbigintbooleansymbolnullundefined

一个对象:

  • 能够存储多个值作为属性。
  • 可以使用大括号 {} 创建对象,例如:{name: "John", age: 30}。JavaScript 中还有其他种类的对象,例如函数就是对象。


关于对象的最好的事儿之一是,我们可以把一个函数作为对象的属性存储到对象中。


let john = {
  name: "John",
  sayHi: function() {
    alert("Hi buddy!");
  }
};
john.sayHi(); // Hi buddy!


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

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


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

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


当作对象的原始类型


以下是 JavaScript 创建者面临的悖论:


  • 人们可能想对诸如字符串或数字之类的原始类型执行很多操作。最好使用方法来访问它们。
  • 原始类型必须尽可能简单轻量。


而解决方案看起来多少有点尴尬,如下:


  1. 原始类型仍然是原始的。与预期相同,提供单个值
  2. JavaScript 允许访问字符串,数字,布尔值和 symbol 的方法和属性。
  3. 为了使它们起作用,创建了提供额外功能的特殊“对象包装器”,使用后即被销毁。

“对象包装器”对于每种原始类型都是不同的,它们被称为 StringNumberBooleanSymbolBigInt。因此,它们提供了不同的方法。


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


用法演示如下:


let str = "Hello";
alert( str.toUpperCase() ); // HELLO


很简单,对吧?以下是 str.toUpperCase() 中实际发生的情况:

  1. 字符串 str 是一个原始值。因此,在访问其属性时,会创建一个包含字符串字面值的特殊对象,并且具有可用的方法,例如 toUpperCase()
  2. 该方法运行并返回一个新的字符串(由 alert 显示)。
  3. 特殊对象被销毁,只留下原始值 str


所以原始类型可以提供方法,但它们依然是轻量级的。


JavaScript 引擎高度优化了这个过程。它甚至可能跳过创建额外的对象。但是它仍然必须遵守规范,并且表现得好像它创建了一样。


数字有其自己的方法,例如,toFixed(n)[2] 将数字舍入到给定的精度:


let n = 1.23456;
alert( n.toFixed(2) ); // 1.23


我们将在后面 info:number 和 info:string 章节中看到更多具体的方法。


构造器 String/Number/Boolean 仅供内部使用


像 Java 这样的一些语言允许我们使用 new Number(1)new Boolean(false) 等语法,明确地为原始类型创建“对象包装器”。


在 JavaScript 中,由于历史原因,这也是可以的,但极其 不推荐。因为这样会出问题。

例如:


alert( typeof 0 ); // "number"
alert( typeof new Number(0) ); // "object"!


对象在 if 中始终为真,所以此处的 alert 将显示:


let zero = new Number(0);
if (zero) { // zero 为 true,因为它是一个对象
  alert( "zero is truthy?!?" );
}


另一方面,调用不带 new(关键字)的 String/Number/Boolean 函数是可以的且有效的。它们将一个值转换为相应的类型:转成字符串、数字或布尔值(原始类型)。

例如,下面完全是有效的:


let num = Number("123"); // 将字符串转成数字


null/undefined 没有任何方法


特殊的原始类型 nullundefined 是例外。它们没有对应的“对象包装器”,也没有提供任何方法。从某种意义上说,它们是“最原始的”。


尝试访问这种值的属性会导致错误:


alert(null.test); // error


总结


  • nullundefined 以外的原始类型都提供了许多有用的方法。我们后面的章节中学习这些内容。
  • 从形式上讲,这些方法通过临时对象工作,但 JavaScript 引擎可以很好地调整,以在内部对其进行优化,因此调用它们并不需要太高的成本。


习题


先自己做题目再看答案。


我能为字符串添加一个属性吗?


重要程度:🌟🌟🌟🌟🌟

思考下面的代码:


let str = "Hello";
str.test = 5;
alert(str.test);

你怎么想的呢,它会工作吗?会得到什么样的结果?


答案


请见:原始类型的方法章节习题和答案

目录
相关文章
|
5天前
|
JavaScript 前端开发
javascript操作BOM的方法
javascript操作BOM的方法
13 0
|
1天前
|
JavaScript 前端开发
在JavaScript中实现模块化开发有多种方法
JavaScript模块化开发可通过CommonJS、AMD和ES6模块实现。CommonJS适用于服务器端,使用`require`和`module.exports`处理模块;AMD(如RequireJS)用于浏览器端,依赖`require`和`define`;ES6模块提供原生支持,使用`import`和`export`。选择方式需考虑项目环境、复杂度和技术栈。
10 4
|
2天前
|
JavaScript 前端开发
JS tostring()和join()方法
JS tostring()和join()方法
7 1
|
2天前
|
存储 JavaScript 前端开发
深入了解JavaScript中的indexOf()方法:实现数组元素的搜索和索引获取
深入了解JavaScript中的indexOf()方法:实现数组元素的搜索和索引获取
7 0
|
2天前
|
存储 JavaScript 前端开发
JavaScript 中松散类型的理解
JavaScript 中松散类型的理解
6 1
|
3天前
|
JavaScript 前端开发
JS中运算符的算术、赋值、+、比较(不同类型之间比较)、逻辑
JS中运算符的算术、赋值、+、比较(不同类型之间比较)、逻辑
6 1
|
3天前
|
JavaScript 前端开发 索引
js添加、删除、替换、插入元素的方法
js添加、删除、替换、插入元素的方法
10 0
|
4天前
|
JavaScript 前端开发
JavaScript 循环方法详解
JavaScript 循环方法详解
17 1
|
4天前
|
JavaScript 前端开发
JavaScript数字方法详解
JavaScript数字方法详解
16 0
|
4天前
|
存储 JavaScript 前端开发
JavaScript对象方法详解
JavaScript对象方法详解
13 1