重学前端-js类型

news2024/12/29 9:22:27

javascript目前位置一共有7种数据类型,分别为:

  1. Undefined;
  2. Null;
  3. Boolean;
  4. String;
  5. Number;
  6. Symbol;
  7. Object。

Undefined与Null

Undefined 类型表示未定义,它的类型只有一个值,就是 undefined,任何变量在赋值前是 Undefined 类型、值为 undefined。有些编程规范要求用 void 0 代替 undefined,是因为 JavaScript 的代码 undefined 是一个变量,而并非是一个关键字,这是 JavaScript 语言公认的设计失误之一,所以,我们为了避免无意中被篡改,我建议使用 void 0 来获取 undefined 值。

var undefined = 1;
console.log(undefined); // 输出: 1

var undefined = void 0;
console.log(undefined); // 输出: undefined

Undefined 跟 Null 有一定的表意差别,Null 表示的是:“定义了但是为空”。所以,在实际编程时,我们一般不会把变量赋值为 undefined,这样可以保证所有值为 undefined 的变量,都是从未赋值的自然状态。 Null 类型也只有一个值,就是 null,它的语义表示空值,与 undefined 不同,null 是 JavaScript 关键字,所以在任何代码中,你都可以放心用 null 关键字来获取 null 值。

Boolean

Boolean 类型有两个值, true 和 false,它用于表示逻辑意义上的真和假。

String

String 用于表示文本数据。String 有最大长度是 2^53 - 1。因为 String 的意义并非“字符串”,而是字符串的 UTF16 编码,我们字符串的操作 charAt、charCodeAt、length 等方法针对的都是 UTF16 编码。所以,字符串的最大长度,实际上是受字符串的编码长度影响的。

var str = "Hello World";

console.log(str.charCodeAt(0)); // 输出: 72
console.log(str.charCodeAt(1)); // 输出: 101
console.log(str.charCodeAt(2)); // 输出: 108

console.log(str.length); // 输出: 11

Number

 Number 类型表示我们通常意义上的“数字”。但是在计算机中, Number 类型有一定的精度限制。

  console.log( 0.1 + 0.2 == 0.3); // false
  console.log( 0.1 + 0.2 ); // 0.30000000000000004

这里输出的结果是 false,说明两边不相等的,这是浮点运算的特点,也是很多同学疑惑的来源,浮点数运算的精度问题导致等式左右的结果并不是严格相等,而是相差了个微小的值。想要解决精度缺失的最简单方法是将小数转成整数进行处理之后再缩小原来放大的倍数。

所以实际上,这里错误的不是结论,而是比较的方法,正确的比较方法是使用 JavaScript 提供的最小精度值:

  console.log( Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON);

检查等式左右两边差的绝对值是否小于最小精度,才是正确的比较浮点数的方法。这段代码结果就是 true 了。

Symbol

Symbol 是 ES6 中引入的新类型,它是一切非字符串的对象 key 的集合,在 ES6 规范中,整个对象系统被用 Symbol 重塑。

Symbol 可以具有字符串类型的描述,但是即使描述相同,Symbol 也不相等。

Object

Object 是 JavaScript 中最复杂的类型,也是 JavaScript 的核心机制之一。Object 表示对象的意思,它是一切有形和无形物体的总称。

提到对象,我们必须要提到一个概念:类。

JavaScript 中的几个基本类型,都在对象类型中有一个“亲戚”。它们是:

  1. Number;
  2. String;
  3. Boolean;
  4. Symbol。

所以,我们必须认识到 3 与 new Number(3) 是完全不同的值,它们一个是 Number 类型, 一个是对象类型。

Number、String 和 Boolean,三个构造器是两用的,当跟 new 搭配时,它们产生对象,当直接调用时,它们表示强制类型转换。

var a = "1"
console.log(Number(a)) // 1 ,number类型
console.log(Number(a)===new Number(a)) //false,因为new Number(1)是对象

为什么给对象添加的方法能用在基本类型上?我们来看个例子:

    Symbol.prototype.hello = () => console.log("hello");

    var a = Symbol("a");
    console.log(typeof a); //symbol,a并非对象
    a.hello(); //hello,有效

答案就是 .  运算符提供了装箱操作,它会根据基础类型构造一个临时对象,使得我们能在基础类型上调用对应对象的方法。

类型转换

因为 JS 是弱类型语言,所以类型转换发生非常频繁,大部分我们熟悉的运算都会先进行类型转换。大部分类型转换符合人类的直觉,但是如果我们不去理解类型转换的严格定义,很容易造成一些代码中的判断失误。

开发中,不推荐用==来实现跨类型比较,推荐先进行显式地类型转换后,用 === 比较。

转换规则如下:

装箱转换

每一种基本类型 Number、String、Boolean、Symbol 在对象中都有对应的类,所谓装箱转换,正是把基本类型转换为对应的对象,它是类型转换中一种相当重要的种类。

前文提到,全局的 Symbol 函数无法使用 new 来调用,但我们仍可以利用装箱机制来得到一个 Symbol 对象,我们可以利用一个函数的 call 方法来强迫产生装箱。

我们定义一个函数,函数里面只有 return this,然后我们调用函数的 call 方法到一个 Symbol 类型的值上,这样就会产生一个 symbolObject。

我们可以用 console.log 看一下这个东西的 type of,它的值是 object,我们使用 symbolObject instanceof 可以看到,它是 Symbol 这个类的实例,我们找它的 constructor 也是等于 Symbol 的,所以我们无论从哪个角度看,它都是 Symbol 装箱过的对象:

    var symbolObject = (function(){ return this; }).call(Symbol("a"));

    console.log(typeof symbolObject); //object
    console.log(symbolObject instanceof Symbol); //true
    console.log(symbolObject.constructor == Symbol); //true

装箱机制会频繁产生临时对象,在一些对性能要求较高的场景下,我们应该尽量避免对基本类型做装箱转换。

使用内置的 Object 函数,我们可以在 JavaScript 代码中显式调用装箱能力。

    var symbolObject = Object(Symbol("a"));

    console.log(typeof symbolObject); //object
    console.log(symbolObject instanceof Symbol); //true
    console.log(symbolObject.constructor == Symbol); //true

每一类装箱对象皆有私有的 Class 属性,这些属性可以用 Object.prototype.toString 获取,Object.prototype.toString 是可以准确识别对象对应的基本类型的方法。

    var symbolObject = Object(Symbol("a"));

    console.log(Object.prototype.toString.call(symbolObject)); //[object Symbol]

拆箱转换

对象到 String 和 Number 的转换都遵循“先拆箱再转换”的规则。通过拆箱转换,把对象变成基本类型,再从基本类型转换为对应的 String 或者 Number。

拆箱转换会尝试调用 valueOf 和 toString 来获得拆箱后的基本类型。如果 valueOf 和 toString 都不存在,或者没有返回基本类型,则会产生类型错误 TypeError。

    var o = {
        valueOf : () => {console.log("valueOf"); return {}},
        toString : () => {console.log("toString"); return {}}
    }

    o * 2
    // valueOf
    // toString
    // TypeError

我们定义了一个对象 o,o 有 valueOf 和 toString 两个方法,这两个方法都返回一个对象,然后我们进行 o*2 这个运算的时候,你会看见先执行了 valueOf,接下来是 toString,最后抛出了一个 TypeError,这就说明了这个拆箱转换失败了。

到 String 的拆箱转换会优先调用 toString。我们把刚才的运算从 o*2 换成 String(o),那么你会看到调用顺序就变了。

    var o = {
        valueOf : () => {console.log("valueOf"); return {}},
        toString : () => {console.log("toString"); return {}}
    }

   String(o)
    // toString
    // valueOf
    // TypeError

JavaScript 对象的两类属性

第一类属性,数据属性。它比较接近于其它语言的属性概念。数据属性具有四个特征。

  • value:就是属性的值。
  • writable:决定属性能否被赋值。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

第二类属性是访问器(getter/setter)属性,它也有四个特征。

  • getter:函数或 undefined,在取属性值时被调用。
  • setter:函数或 undefined,在设置属性值时被调用。
  • enumerable:决定 for in 能否枚举该属性。
  • configurable:决定该属性能否被删除或者改变特征值。

我们通常用于定义属性的代码会产生数据属性,其中的 writable、enumerable、configurable 都默认为 true。我们可以使用内置函数 getOwnPropertyDescriptor 来查看,如以下代码所示:

    var o = { a: 1 };
    o.b = 2;
    //a和b皆为数据属性
    Object.getOwnPropertyDescriptor(o,"a") // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b") // {value: 2, writable: true, enumerable: true, configurable: true}

如果我们要想改变属性的特征,或者定义访问器属性,我们可以使用 Object.defineProperty,示例如下:

    var o = { a: 1 };
    Object.defineProperty(o, "b", {value: 2, writable: false, enumerable: false, configurable: true});
    //a和b都是数据属性,但特征值变化了
    Object.getOwnPropertyDescriptor(o,"a"); // {value: 1, writable: true, enumerable: true, configurable: true}
    Object.getOwnPropertyDescriptor(o,"b"); // {value: 2, writable: false, enumerable: false, configurable: true}
    o.b = 3;
    console.log(o.b); // 2

在创建对象时,也可以使用 get 和 set 关键字来创建访问器属性,代码如下所示:

    var o = { get a() { return 1 } };

    console.log(o.a); // 1

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1109780.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1455. 检查单词是否为句中其他单词的前缀

1455. 检查单词是否为句中其他单词的前缀 JS代码&#xff1a;js就很便捷&#xff01;startsWith() /*** param {string} sentence* param {string} searchWord* return {number}*/ var isPrefixOfWord function(sentence, searchWord) {let arr sentence.split( );for (let …

JavaScript处理按键事件-模态窗口

上一节中我们基本实现了模态窗口的功能&#xff0c;本文将介绍我们可以通过用户的按键然后去执行一些事情 document.addEventListener(keydown,function() {console.log("我按下了一个按键"); })这段代码会添加一个事件监听器&#xff0c;当有键盘按键被按下时&#…

权威认证!海云安获得数据安全服务能力评定资格证书

为切实提升数据安全保障能力&#xff0c;加速推进国家数据安全建设&#xff0c;中国计算机行业协会数据安全专业委员会依托能力评价工作组从数据安全评估和数据安全建设两个方面开展了数据安全服务能力评定。 经过自主申报、专家评审等程序&#xff0c;深圳海云安网络安全技术…

TCP/IP(二十二)TCP 实战抓包分析(六)TCP 快速建立连接

一 TCP Fast Open 快速建立连接 说明&#xff1a; 之前讲解TCP 相关知识点遗漏了这个知识点,补充上 ① TFO简介 ② 请求 Fast Open Cookie过程 "原理图" ③ 真正开始 TCP Fast Open 重点&#xff1a; TFO 使 SYN包 可以包含payload 数据 ④ 抓包分析 1、…

使用单个mybatis框架进行mysql数据库的连接和操作?

使用单个mybatis框架进行mysql数据库的操作&#xff1f; 简述 先来说一下数据库连接的演变&#xff0c;刚开始的时候&#xff0c;最原生的连接并操作mysql数据库的办法是使用JDBC技术&#xff0c;这种技术相对来说写的源码比较多&#xff0c;比较繁杂&#xff1b; 后来就出现…

第十六届中国智慧城市大会 | 国产化三维重建技术服务智慧城市建设

2023年10月13日&#xff0c;由武汉大势智慧科技有限公司、飞燕航空遥感技术有限公司主办的第十六届智慧城市大会-实景三维技术创新与应用论坛在广州成功举办。 来自实景三维、自然资源、数字孪生、AI大数据、航空遥感等多个领域的专家&#xff0c;深度分享各自的智慧城市建设经…

【2023双十一新玩法】如何快速让数据达到预期目的,让销售额提升10倍,客群提升10倍,销量提升10倍

2023年的双十一即将到来&#xff0c;商家们依然在为销售目标而努力&#xff0c;而数据分析就成为了其中不可或缺的一环。大大小小的企业都纷纷采用了数据分析来提高销售效率&#xff0c;而老板们也都习惯了看着大屏幕上的实时数据。 然而&#xff0c;对于员工而言&#xff0c;做…

在线商城系统软件、源码、报价_OctShop

随着互联网、5G、人工智能的快速发展&#xff0c;人们在家购物已经是生活的重要方式。各种在线商城系统的不断涌现&#xff0c;同时&#xff0c;也给传统的企业商家销售带来了不小的压力&#xff0c;那么&#xff0c;如何调整&#xff0c;以适应时代的发展呢&#xff1f;经过不…

把Resources目录标记为Resource Root目录才能找到文件?

把Resources目录标记为Resource Root目录才能找到文件&#xff1f; mybatis配置文件中配置的mapper.xml映射文件找不到&#xff1f;这是为什么呢&#xff1f;因为你当resources目录不是根目录&#xff0c;重新标记成根目录就可以了&#xff0c;如下图&#xff1a;

Java项目-网页聊天程序

目录 项目介绍 项目功能简介 项目创建 用户管理模块 1.数据库设计及代码实现 2.前后端交互接口的设计 3.服务器代码开发 好友管理模块 数据库设计 好友表设计的两个重要问题 设计前后端交互接口 服务器代码 会话管理模块 会话的数据库设计 获取会话信息 约定前后…

VisualStudio 远程Debug

注意&#xff1a;纯靠记性&#xff0c;可能实际有出入。 1.连接本地电脑和远程电脑&#xff0c;我是通过ToDesk软件进行桌面连接的。 2.本地运行的项目&#xff0c;把项目打包后拷贝到远程电脑。 3.打开本地VisualStudio的安装位置&#xff0c;有个文件夹叫Remote Debugger。把…

深入研究Java线程Dump分析:掌握发现和解决多线程问题的关键技巧

1 Thread Dump介绍 1.1 什么是Thread Dump Thread Dump是非常有用的诊断Java应用问题的工具。每一个Java虚拟机都有及时生成所有线程在某一点状态的thread-dump的能力&#xff0c;虽然各个 Java虚拟机打印的thread dump略有不同&#xff0c;但是大多都提供了当前活动线程的快…

“乘风而上,谋远共赢”润和软件HopeStage2023秋季渠道商会议圆满举行 润和软件 润和软件

10月18日&#xff0c;由江苏润和软件股份有限公司&#xff08;以下简称“润和软件”&#xff09;主办的HopeStage2023秋季渠道商会议圆满举行。本次会议以“乘风而上&#xff0c;谋远共赢”为主题&#xff0c;汇聚众多HopeStage渠道商与生态合作伙伴&#xff0c;共谋国产基础软…

怎么把本机设置成代理ip?

代理IP服务能帮助您隐藏您的真实IP&#xff0c;从而保护您的隐私和安全。本文将指导您如何将本机设置为代理IP。代理IP服务能帮助您隐藏您的真实IP&#xff0c;从而保护您的隐私和安全。本文将指导您如何将本机设置为代理IP。设置代理IP可以用于多种用途&#xff0c;比如&#…

进程相关内容(三)

目录 进程优先级 进程饥饿 Linux当中优先级标识符 优先级的修改参数NI 进程最终优先级 修改进程的优先级 操作系统实现优先级的方法 位图 并发的概念 进程切换原理 环境变量 其他环境变量 获得环境变量的方式 getenv系统调用函数 命令行参数 本地变量 export添加环境变量 unset…

修改echarts的tooltip样式 折线图如何配置阴影并实现渐变色和自适应

图片展示 一、引入echarts 这里不用多解释 vue里使用 import echarts from “echarts”; html页面引用js文件或用script标签引用 二、定义一个具有宽高的dom div <div id"echart-broken" style"width:400px;height: 200px;"></div>三、定义…

头歌平台——基于数组的工资处理系统

第1关&#xff1a;数据输入和计算 任务描述 本关任务&#xff1a; 编写函数input_data(char uid[10][5], int salary[10], int csalary[10], int revenue[10], int _water_electricity[10], int _deductions[10])&#xff0c;作用为输入职工的代号&#xff0c;岗位工资&#…

LabVIEW应用开发——控件的使用(二)

上篇介绍数值型控件和布尔型控件&#xff0c;这篇介绍字符串、路径控件、下拉框和数组控件。 LabVIEW应用开发——控件的使用&#xff08;一&#xff09; 1、字符串控件 实际应用中&#xff0c;字符串控件的显示很常用的&#xff0c;可用于显示串口信息、通讯交互信息、…

JAVA-记一次BigDecimal,String千分位转换

在显示类上面添加JsonSerialize注解&#xff0c;指定对应的转换格式例如&#xff0c;同理可在属性为BigDecimal的字段上添加注解&#xff0c;指定方法&#xff1a; private String userTypeStr;/*** 交易金额*/JsonSerialize(using StringSerialize.class)private String tran…

零基础制作电子期刊,不用担心不会设计排版

亲爱的朋友们&#xff0c;你是否想制作一本自己的电子期刊&#xff0c;但又担心不会设计排版&#xff1f;别担心&#xff01;今天我将教你如何零基础制作电子期刊&#xff0c;让你轻松上手&#xff01; 首先&#xff0c;你需要选择一个适合你的电子期刊模板。我们可以使用FLBOO…