在JavaScript中一切都是对象吗?

2023-12-25 04:18

本文主要是介绍在JavaScript中一切都是对象吗?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接:http://web.jobbole.com/82016/

“在JavaScript中的一切都是对象”这个说法一直让我困惑。他们指的是什么?一个函数或者数组,它们怎么同时也是一个对象?在我们解答这个问题前,我们需要知道JavaScript是如何对不同数据类型归类的。

数据类型

在JavaScript中,有两个数据类型:基本类型和对象类型(对象类型有时候也被称为引用类型)。

基本类型

Number, String, Boolean, null, undefined

对象类型

Function, Object, Array

根据这个分类,这个问题的简单答案是:JavaScript中,并非一切值都是对象。是只有属于对象类型的值才是对象。也可以认为,任何非基本类型的都是对象类型。但是基本类型和对象类型有什么区别呢?更重要的是,人们所说的“所有”或“几乎所有”的JavaScript类似都是对象的真正含义是什么?这里说说主要的两个区别:可变性和比较。

Mutability可变性

根据我的经验,人们说的值是“类似对象”的真实含义是因为他们的可变性,更具体的说,是支持添加和删除属性。例如,因为函数和数组属于对象类型,你可以像对象一样给它们添加属性。

var func = function() {};
func.firstName = "Andrew";
func.firstName; // "Andrew"var arry = [];
arry.age = 26;
arry.age; // 26

可变性开启了各种精彩的使用方式,也是理解原型和构造函数是如何工作的关键。

但是基本类型是不可变的,我们无法给它们添加属性。如下面代码所示,即使我们给基本类型添加了属性,解析器会无法在下一步读取它们的值。

var me = "Andrew";
me.lastname = "Robbins";
me.lastname; // undefinedvar num = 10;
num.prop = 11;
num.prop; // undefined

在这一点上,基本类型的值无法改变的真正含义,需要在更基本的层面检查问题,如下代码所示:

1 = 2; // ReferenceError

这似乎是一个愚蠢的例子,但是我认为能反映出我们现在讨论的可变性,当你在JavaScript控制器中输入数字 1,编译器会给其分配基本类型,所以当你尝试将数字1改变成数字2会失败。

比较和传递

除了可变性,另外一个基本类型和对象类型重要的区别是他们在程序中比较和传递的方式。基本类型通过值来比较,而对象类型通过引用来比较,这是什么意思呢?我们先看看基本类型,如下代码所示:

"a" === "a"; // true

因为值“a”等于“a”所以为true,当我们在图中引入变量会发生什么呢?除了将一个基本类型储存在变量中什么也没发生。

var a = "a",b = "a";a === b; // true

当基本类型通过值来比较,结果为true,变量a的值正好等于变量b的值,换句话说,”a”等于”a”。但是看看下面这个例子,如果我们在对象类型中应用相同的例子,我们会得到相反的结果。

var a = {name: "andrew"},b = {name: "andrew"};a === b; // false

为什么会这样呢?如果想要两者比较为真需要对象类型要引用同样的类型。通过以上的例子,我们给变量b创建一个新的对象。就像David Flanagan说过:我们说的通过引用进行对象比较是:两个对象的值是否相同取决于它们是否指向相同的底层对象。

那我们这样传值会发生什么?

var a = {name: "andrew"},b = a;b.name = "robbins";a === b; // true

这个可能开始看上去很奇怪,但是仔细看看发生了什么,因为对象是对象类型的一部分,它比较的值是按引用进行传递。引用的是相同的底层对象。在以上的例子中,我们设置b等于a。并没有创建新对象,我们只是简单地创建了一个对其他对象的引用。从另一个方面来看我们是将变量b指向a,所以当我们改变b的name属性,我们同样改变了a的name属性。

如果将相同的例子应用在基本类型上呢?

var a = "Andrew",b = a;b = "Robbins";a === b; // false

当我们设置b等于a,请记住基本类型通过值来传递和比较,我们实际上另外创建了一个a的拷贝,所以我们改变b的值再跟a比较,两个值是不一样的。

Wrapper Objects包装对象

有些人会说:“好,如果基本类型不是对象,为什么我们可以调用他们的方法呢” 回答是包装对象。

当你尝试调用基本类型的方法,JavaScript在幕后做了一个巧妙的处理,将你的基本类型的值转换成临时对象用于构造函数,决定使用哪个构造函数取决于你尝试改变的基本类型的值,在String中调用.length会使用string()构造函数临时将基本类型转变成对象—允许你使用length方法而改变它,这个临时对象被称为包装对象。

有趣的是,null和undefined这两个基本类型不能调用这样的方法,否则会提示类型错误。

我们可以使用typeof来区分:

typeof "s"; // "string"
typeof new String(s); // "object"

备注:在执行typeof null 时js编译器会返回object,是显而易见的bug。

typeof null // "object"

当然,考虑到JavaScript是用10天写出来(http://www.quora.com/In-which-10-days-of-May-did-Brendan-Eich-write-JavaScript-Mocha-in-1995),就不过多去担忧了 :) 。

此外,我们也需要了解基本类型的属性是只读和临时的。

var hello = "hello";
hello.slice(1); // "ello" (Here we're actually calling slice not on hello, but of a copy of hello)
hello; // "hello"

Summary总结

JavaScript的值可以分为两种类型:基本类型和对象类型,基本类型有:String, Number, Boolean, Symbol, undefined 和 null.,对象类型有Function, Object 和 Array.

基本类型和对象类型的区别在于可变性和比较的方式以及程序中传值。

基本类型是不可变的,换种说法就是它们的值不能改变。对比而言,对象类型是可变的,它们的值可以更新和改变。

基本类型可以按值比较,当我们把一个基本类型赋值给另外一个基本类型,是复制了一个值。而对象这是通过引用进行比较,引用的是什么呢?引用的是底层对象。当我们赋值一个对象给另一个对象时。引用指针就创建了。在这个情况下,改变一个对象的值将更新另外一个对象的值。

当我们尝试在基本类型的值中调用方法时,JavaScript使用包装对象来临时控制基本类型,导致对象变为只读的并在垃圾回收后执行。

这篇关于在JavaScript中一切都是对象吗?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/534236

相关文章

Java对象和JSON字符串之间的转换方法(全网最清晰)

《Java对象和JSON字符串之间的转换方法(全网最清晰)》:本文主要介绍如何在Java中使用Jackson库将对象转换为JSON字符串,并提供了一个简单的工具类示例,该工具类支持基本的转换功能,... 目录前言1. 引入 Jackson 依赖2. 创建 jsON 工具类3. 使用示例转换 Java 对象为

SpringBoot快速接入OpenAI大模型的方法(JDK8)

《SpringBoot快速接入OpenAI大模型的方法(JDK8)》本文介绍了如何使用AI4J快速接入OpenAI大模型,并展示了如何实现流式与非流式的输出,以及对函数调用的使用,AI4J支持JDK8... 目录使用AI4J快速接入OpenAI大模型介绍AI4J-github快速使用创建SpringBoot

Java中的Cursor使用详解

《Java中的Cursor使用详解》本文介绍了Java中的Cursor接口及其在大数据集处理中的优势,包括逐行读取、分页处理、流控制、动态改变查询、并发控制和减少网络流量等,感兴趣的朋友一起看看吧... 最近看代码,有一段代码涉及到Cursor,感觉写法挺有意思的。注意是Cursor,而不是Consumer

解决java.lang.NullPointerException问题(空指针异常)

《解决java.lang.NullPointerException问题(空指针异常)》本文详细介绍了Java中的NullPointerException异常及其常见原因,包括对象引用为null、数组元... 目录Java.lang.NullPointerException(空指针异常)NullPointer

javaScript在表单提交时获取表单数据的示例代码

《javaScript在表单提交时获取表单数据的示例代码》本文介绍了五种在JavaScript中获取表单数据的方法:使用FormData对象、手动提取表单数据、使用querySelector获取单个字... 方法 1:使用 FormData 对象FormData 是一个方便的内置对象,用于获取表单中的键值

前端知识点之Javascript选择输入框confirm用法

《前端知识点之Javascript选择输入框confirm用法》:本文主要介绍JavaScript中的confirm方法的基本用法、功能特点、注意事项及常见用途,文中通过代码介绍的非常详细,对大家... 目录1. 基本用法2. 功能特点①阻塞行为:confirm 对话框会阻塞脚本的执行,直到用户作出选择。②

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

Java实战之利用POI生成Excel图表

《Java实战之利用POI生成Excel图表》ApachePOI是Java生态中处理Office文档的核心工具,这篇文章主要为大家详细介绍了如何在Excel中创建折线图,柱状图,饼图等常见图表,需要的... 目录一、环境配置与依赖管理二、数据源准备与工作表构建三、图表生成核心步骤1. 折线图(Line Ch

Spring Boot 3 整合 Spring Cloud Gateway实践过程

《SpringBoot3整合SpringCloudGateway实践过程》本文介绍了如何使用SpringCloudAlibaba2023.0.0.0版本构建一个微服务网关,包括统一路由、限... 目录引子为什么需要微服务网关实践1.统一路由2.限流防刷3.登录鉴权小结引子当前微服务架构已成为中大型系统的标

Java集合中的List超详细讲解

《Java集合中的List超详细讲解》本文详细介绍了Java集合框架中的List接口,包括其在集合中的位置、继承体系、常用操作和代码示例,以及不同实现类(如ArrayList、LinkedList和V... 目录一,List的继承体系二,List的常用操作及代码示例1,创建List实例2,增加元素3,访问元