在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

相关文章

springboot健康检查监控全过程

《springboot健康检查监控全过程》文章介绍了SpringBoot如何使用Actuator和Micrometer进行健康检查和监控,通过配置和自定义健康指示器,开发者可以实时监控应用组件的状态,... 目录1. 引言重要性2. 配置Spring Boot ActuatorSpring Boot Act

使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)

《使用Java解析JSON数据并提取特定字段的实现步骤(以提取mailNo为例)》在现代软件开发中,处理JSON数据是一项非常常见的任务,无论是从API接口获取数据,还是将数据存储为JSON格式,解析... 目录1. 背景介绍1.1 jsON简介1.2 实际案例2. 准备工作2.1 环境搭建2.1.1 添加

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

java如何分布式锁实现和选型

《java如何分布式锁实现和选型》文章介绍了分布式锁的重要性以及在分布式系统中常见的问题和需求,它详细阐述了如何使用分布式锁来确保数据的一致性和系统的高可用性,文章还提供了基于数据库、Redis和Zo... 目录引言:分布式锁的重要性与分布式系统中的常见问题和需求分布式锁的重要性分布式系统中常见的问题和需求

SpringBoot基于MyBatis-Plus实现Lambda Query查询的示例代码

《SpringBoot基于MyBatis-Plus实现LambdaQuery查询的示例代码》MyBatis-Plus是MyBatis的增强工具,简化了数据库操作,并提高了开发效率,它提供了多种查询方... 目录引言基础环境配置依赖配置(Maven)application.yml 配置表结构设计demo_st

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

SpringCloud集成AlloyDB的示例代码

《SpringCloud集成AlloyDB的示例代码》AlloyDB是GoogleCloud提供的一种高度可扩展、强性能的关系型数据库服务,它兼容PostgreSQL,并提供了更快的查询性能... 目录1.AlloyDBjavascript是什么?AlloyDB 的工作原理2.搭建测试环境3.代码工程1.

Java调用Python代码的几种方法小结

《Java调用Python代码的几种方法小结》Python语言有丰富的系统管理、数据处理、统计类软件包,因此从java应用中调用Python代码的需求很常见、实用,本文介绍几种方法从java调用Pyt... 目录引言Java core使用ProcessBuilder使用Java脚本引擎总结引言python