我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript中的数据类型与变量有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript中的数据类型与变量有哪些

JavaScript中的数据类型与变量有哪些,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

基本数据类型

在 JS 中,基本数据类型有 6 种,即数值、字符串、布尔值、null、undefined、Symbol。

对于基本数据类型,我们需要明白的是:基本类型在内存中的存储方式是栈。每一个值都是单独存放,互不影响。

基本类型都是按值访问的。在比较时,按值进行比较:

1 === 1 // true

引用数据类型

引用类型的值保存在堆中,而引用是保存在栈中。

引用类型按引用访问。在比较时,也比较的引用:

{} === {} // => false

参数的传递方式

在 JS 中,参数可以是任何类型的值,甚至可以是函数。

这里要分析的是参数是以哪种类型传递的?引用类型还是基本类型?

先看一个基础的例子:

var out_num = 1;  function addOne(in_num) {  in_num += 1;  return in_num;  }  addOne(out_num); // => 2  out_num // => 1

这个例子中,我们给 addOne() 函数传递一个实参 out_num,这个时 out_num 会传递给 in_num,即内部存在着 in_num =  out_num 的过程。***我们看到的结果是 out_num 并没有被函数改变,说明 in_num 和 out_num  是两个在内存中独立存放的值,即按值传递。

再来看一个变形:

var out_obj = { value: 1 };  function addOne(in_obj) {  in_obj.value += 1;  return in_obj;  }  addOne(out_obj); // => { value: 2 }  out_obj // => { value: 2 }

问题来了?函数参数不是按值传递吗?为什么这里函数内部的处理反映到外部了?这是一个超级超级超级的理解误区。

首先,我们还是得摆正观点,即函数参数是按值传递的。那这里怎么理解呢?对于引用类型而言,前面说引用类型分为引用和实际的内存空间。在这里 out_obj  依旧传递给 in_obj,即 in_obj = out_obj ,out_obj 和 in_obj  是两个引用,它们在内存中的存储方式是独立的,但是它们却指向同一块内存。

而 in_obj.value = 1 则是直接操作的实际对象。实际对象的改变,会同步到所有引用这个实际对象的引用。

JavaScript中的数据类型与变量有哪些

你再来看这个例子,或许就会更清晰一些。

var out_obj = { value: 1 };  function addOne(in_obj) {  in_obj = { value: 2 };  return in_obj;  }  addOne(out_obj); // => { value: 2 }  out_obj // => { value: 1 }

你只要抓住一点:对象的赋值就会造成引用指向的实际对象发生改变。

如何判断数据类型

判断数据类型,通常有三种具体的方法:

1、typeof 操作符

typeof 操作符返回一个表示数据类型的字符串。它存在以下明显的缺陷:

typeof null // => 'object'  typeof [] // => 'object'

这是因为在 JS 语言设计之初遗留的 bug。可以阅读这篇文章 http://2ality.com/2013/10/typ... 了解更多关于  typeof 处理 null 的问题。

所以 typeof ***用于判断一些基本类型,比如数值、字符串、布尔值、undefined、Symbol。

2、instanceof 操作符

typeof 的背后是通过判断 type tags 来判断数据类型,而 instanceof 则是通过判断构造函数的 prototype  是否出现在对象原型链上的任何位置。

举个例子:

{} instanceof Object // => true  [] instanceof Array // => true  [] instanceof Object // => true

也判断自定义类型:

function Car(make, model, year) {  this.make = make;  this.model = model;  this.year = year;  }  var auto = new Car('Honda', 'Accord', 1998);  console.log(auto instanceof Car);  // => true  console.log(auto instanceof Object);  // => true

所以,对于字面量形式的基本数据类型,不能通过 instanceof 判断:

1 instanceof Number // => false  Number(1) instanceof Number // => false  new Number(1) instanceof Number // => true

3、Object.prototype.toString()

这是目前最为推荐的一种方法,可以更加精细且准确的判断任何数据类型,甚至是 JSON、正则、日期、错误等等。在 Lodash 中,其判断数据类型的核心也是  Object.prototype.toString() 方法。

Object.prototype.toString.call(JSON) // => "[object JSON]"

关于这背后的原理,你可以阅读这篇文章 http://www.cnblogs.com/ziyunf...

4、其他

上面三种是通用的判断数据类型的方法。面试中还会出现如何判断一个数组、如何判断  NaN、如何判断类数组对象、如何判断一个空对象等问题。这一类问题比较开放,解决思路通常是抓住判断数据的核心特点。

举个例子:判断类数组对象。

你先要知道 JS 中类数组对象是什么样子的,并寻求一个实际的参照物,比如 arguments 就是类数组对象。那么类数组对象具有的特点是:真值 &  对象 & 具有 length 属性 & length 为整数 & length 的范围大于等于  0,小于等于***安全正整数(Number.MAX_SAFE_INTEGER)。

在你分析特点的时候,答案就呼之欲出了。【注意全面性】

数据类型如何转换

JS 数据类型的动态性将贯穿整个 JS 的学习,这是 JS 非常重要的特性,很多现象就是因为动态性的存在而成为 JS 独有。

正是由于动态性,JS 的数据类型可能在你毫无察觉的情况下,就发生了改变,直到运行时报错。

这里主要分析下面 8 种转换规则。

1、if 语句

if 语句中的类型转换是最常见的。

if (isTrue) {  // ...  } else {}

在 if 语句中,会自动调用 Boolean() 转型函数对变量 isTrue 进行转换。

当 isTrue 的值是 null, undefined, 0, NaN, '' 时,都会转为 false。其余值除 false 本身外都会转为  true。

2、Number() 转型函数

我们重点关注 null undefined 以及字符串在 Number() 下的转换:

Number(null) // => 0  Number(undefined) // => NaN  Number('') // => 0  Number('123') // => 123  Number('123abc') // => NaN

注意和 parseInt() 对比。

3、parseInt()

parseInt(null) // => NaN  parseInt(undefined) // => NaN  parseInt('') // => NaN  parseInt('123') // => 123  parseInt('123abc') // => 123

4、==

这里需要注意的是:

null == undefined // => true  null == 0 // => false  undefined == false // => false

null 与 undefined 的相等性是由 ECMA-262 规定的,并且 null 与 undefined  在比较相等性时不能转换为其他任何值。

5、关系操作符

对于两个字符串的比较,是比较的字符编码值:

'B' < 'a' // => true

一个数值,另一个其他类型,都将转为数字进行比较。

两个布尔值转为数值进行比较。

对象,先调用 valueOf(),若不存在该方法,则调用 toString()。

6、加法

加法中特别注意的是,数字和字符串相加,将数字转为字符串。

'1' + 2 => // '12'  1 + 2 => // 3

对于对象和布尔值,调用它们的 toString() 方法得到对应的字符串值,然后进行字符串相加。对于 undefined 和 null 调用  String() 取得字符串 'undeifned' 和 'null'。

{ value: 1 } + true // => "[object Object]true"

7、减法

对于字符串、布尔值、null 或者 undefined,自动调用 Number(),转换结果若为 NaN,那么最终结果为 NaN。

对于对象,先调用 valueOf(),如果得到 NaN,结果为 NaN。如果没有 valueOf(),则调用 toString()。

8、乘法、除法

对于非数值,都会调用 Number() 转型函数。

变量提升与暂时性死区

JS 中有三种声明变量的方式:var, let, const。

var 声明变量***的一个特点是存在变量提升。

console.log(a); // undefined  var a = 1;  console.log(a); // 1

***个打印结果表示,在声明变量 a 之前,a 就已经可以访问了,只不过并未赋值。这就是变量提升现象。(具体原因,我放在后面分析作用域的时候来写)

let 和 const 就不存在这个问题,但是又引入了暂时性死区这样的概念。

  let a = 1;  console.log(a); // => 1

即声明 a 之前,不能够访问 a,而直接报错。

而暂时性死区的出现又引出另外一个问题,即 typeof 不再安全。你可以参考这篇文章  http://es-discourse.com/t/why...

补充:一个经典面试题

for (var i = 0; i < 4; i++) {  setTimeout(function(){  console.log(i);  }, i * 1000);  }

我先不再这里展开分析,我打算放到异步与事件循环机制中去分析。不过这里将 var 替换成 let  可以作为一种解决方案。如果你有兴趣,也可以先去分析。

对于 const,这里再补充一点,用于加深对基本类型和引用类型的理解。

const a = 1;  const b = { value: 1 };  a = 2; // => Error  b.value = 2; // => 2  b = { value: 2 }; // => Error

本质上,const 并不是保证变量的值不得改动,而是变量指向的内存地址不得改动。

声明全局变量

直接通过 var 声明全局变量,这个全局变量会作为 window 对象的一个属性。

var a = 1;  window.a // => 1

在这里提出两个问题,一是 let 声明的全局变量会成为 window 的属性吗?二是 var 声明的全局变量和直接在 window  创建属性有没有区别?

先来回答***问题。let 声明的全局变量不会成为 window 的属性。用什么来支撑这样的结论呢?在 ES6 中,对于 let 和 const  声明的变量从一开始就形成封闭作用域。想想之前的暂时性死区。

第二个问题,var 声明的全局变量和直接在 window 创建属性存在着本质的区别。先看下面的代码:

var a = 1;  window.a // => 1  window.b = 2;  delete window.a  delete window.b  window.a // => 1  window.b // => undefined

我们可以看到,直接创建在 window 上的属性可以被 delete 删除,而 var  创建的全局属性则不会。这是现象,通过现象看本质,二者本质上的区别在于:

使用 var 声明的全局变量的 [[configurable]] 数据属性的值为 false,不能通过 delete 删除。而直接在对象上创建的属性默认  [[configurable]] 的值为 true,即可以被 delete 删除。(关于 [[configurable]]  属性,在后面的文章中分析对象的时候还会提到)

看完上述内容,你们掌握JavaScript中的数据类型与变量有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript中的数据类型与变量有哪些

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript的变量和数据类型有哪些

本文小编为大家详细介绍“JavaScript的变量和数据类型有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“JavaScript的变量和数据类型有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。变量1、先
2023-06-27

python中有哪些变量数据类型

本篇文章为大家展示了python中有哪些变量数据类型,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。 python数据类型相关脚本内容如下:#!/usr/bin/env python# _*
2023-06-04

php中变量有哪些基本数据类型

php 中包含以下基本数据类型:1. 整数(存储整数);2. 浮点数(存储小数);3. 字符串(存储文本);4. 数组(存储元素集合);5. 布尔值(存储逻辑值);6. 对象(存储复杂数据结构);7. 资源(引用外部资源);8. null(
php中变量有哪些基本数据类型
2024-04-27

JavaScript的变量与数据类型是什么

这篇文章给大家介绍JavaScript的变量与数据类型是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。前言:我不是搞前端,而是搞后端的。本命编程语言是java。学习js的嘛,因为看到室友能做出动态网页,而我只能做出
2023-06-22

Java中的变量类型有哪些

小编给大家分享一下Java中的变量类型有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、局部变量在方法或语句块中定义的变量被称为局部变量。变量声明和初始化都是在方法中,方法结束后,变量就会自动销毁。局部变量声明在方法
2023-06-25

Python中有哪些变量类型

这篇文章将为大家详细讲解有关Python中有哪些变量类型,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Python是有变量类型的,而且会强制检查变量类型。内置的变量类型有如下几种:整型int
2023-06-17

php中变量类型有哪些

php中变量类型有哪些?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。php是什么语言php,一个嵌套的缩写名称,是英文超级文本预处理语言(PHP:Hypertext Prepr
2023-06-14

JavaScript有哪些数据类型

JavaScript有哪些数据类型?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1、number类型值包括整数、浮点数、NaN、Infinity等。其中NaN类型是js中唯一不
2023-06-15

JavaScript变量类型有哪些及变量间的转换方法

这篇文章主要介绍“JavaScript变量类型有哪些及变量间的转换方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript变量类型有哪些及变量间的转换方法”文章能帮助大家解决问题。1.
2023-06-29

C语言数据类型和变量常量有哪些

这篇“C语言数据类型和变量常量有哪些”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言数据类型和变量常量有哪些”文章吧。首
2023-06-26

Bash变量类型有哪些

这篇文章主要介绍了Bash变量类型有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Bash变量类型有哪些文章都会有所收获,下面我们一起来看看吧。Bash变量类型本地变量局部变量环境变量位置变量特殊变量(内置
2023-06-28

编程热搜

目录