在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

相关文章

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Java Spring ApplicationEvent 代码示例解析

《JavaSpringApplicationEvent代码示例解析》本文解析了Spring事件机制,涵盖核心概念(发布-订阅/观察者模式)、代码实现(事件定义、发布、监听)及高级应用(异步处理、... 目录一、Spring 事件机制核心概念1. 事件驱动架构模型2. 核心组件二、代码示例解析1. 事件定义

SpringMVC高效获取JavaBean对象指南

《SpringMVC高效获取JavaBean对象指南》SpringMVC通过数据绑定自动将请求参数映射到JavaBean,支持表单、URL及JSON数据,需用@ModelAttribute、@Requ... 目录Spring MVC 获取 JavaBean 对象指南核心机制:数据绑定实现步骤1. 定义 Ja

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

Python打印对象所有属性和值的方法小结

《Python打印对象所有属性和值的方法小结》在Python开发过程中,调试代码时经常需要查看对象的当前状态,也就是对象的所有属性和对应的值,然而,Python并没有像PHP的print_r那样直接提... 目录python中打印对象所有属性和值的方法实现步骤1. 使用vars()和pprint()2. 使

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor