在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应用中的实现过程

《分布式锁在SpringBoot应用中的实现过程》文章介绍在SpringBoot中通过自定义Lock注解、LockAspect切面和RedisLockUtils工具类实现分布式锁,确保多实例并发操作... 目录Lock注解LockASPect切面RedisLockUtils工具类总结在现代微服务架构中,分布

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

Spring Boot集成/输出/日志级别控制/持久化开发实践

《SpringBoot集成/输出/日志级别控制/持久化开发实践》SpringBoot默认集成Logback,支持灵活日志级别配置(INFO/DEBUG等),输出包含时间戳、级别、类名等信息,并可通过... 目录一、日志概述1.1、Spring Boot日志简介1.2、日志框架与默认配置1.3、日志的核心作用

破茧 JDBC:MyBatis 在 Spring Boot 中的轻量实践指南

《破茧JDBC:MyBatis在SpringBoot中的轻量实践指南》MyBatis是持久层框架,简化JDBC开发,通过接口+XML/注解实现数据访问,动态代理生成实现类,支持增删改查及参数... 目录一、什么是 MyBATis二、 MyBatis 入门2.1、创建项目2.2、配置数据库连接字符串2.3、入

Springboot项目启动失败提示找不到dao类的解决

《Springboot项目启动失败提示找不到dao类的解决》SpringBoot启动失败,因ProductServiceImpl未正确注入ProductDao,原因:Dao未注册为Bean,解决:在启... 目录错误描述原因解决方法总结***************************APPLICA编

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

SpringBoot多环境配置数据读取方式

《SpringBoot多环境配置数据读取方式》SpringBoot通过环境隔离机制,支持properties/yaml/yml多格式配置,结合@Value、Environment和@Configura... 目录一、多环境配置的核心思路二、3种配置文件格式详解2.1 properties格式(传统格式)1.

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

Spring WebClient从入门到精通

《SpringWebClient从入门到精通》本文详解SpringWebClient非阻塞响应式特性及优势,涵盖核心API、实战应用与性能优化,对比RestTemplate,为微服务通信提供高效解决... 目录一、WebClient 概述1.1 为什么选择 WebClient?1.2 WebClient 与

Java.lang.InterruptedException被中止异常的原因及解决方案

《Java.lang.InterruptedException被中止异常的原因及解决方案》Java.lang.InterruptedException是线程被中断时抛出的异常,用于协作停止执行,常见于... 目录报错问题报错原因解决方法Java.lang.InterruptedException 是 Jav