分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

JS的类型和值

发布时间:2023-09-06 01:53责任编辑:熊小新关键词:暂无标签

1.类型

ECMAScript语言中所有的值都有一个对应的语言类型。ECMAScript语言类型包括Undefined、Null、Boolean、String、Number和Object。
对语言引擎和开发人员来说,类型是值的内部特征,它定义了值的行为,以使其区别于其他值。

内置类型

JavaScript有七种内置类型:

  • 空值(null)
  • 未定义(undefined)
  • 布尔值(boolean)
  • 数字(number)
  • 字符串(string)
  • 对象(object)
  • 符号(symbol,ES6中新增)

除了对象之外,其他统称为“基本类型”。

我们可以用typeof运算符来查看值的类型,它返回的是类型的字符串值。

typeof undefined === "undefined";//truetypeof true === "boolean";//truetypeof 42 === "number";//truetypeof "42" === "string";//truetypeof {life:42} === "object";//truetypeof Symbol() === "symbol";//true//下面是一个bugtypeof null === "object";//truetypeof function a(){ /*...*/ } === "function";//true

JavaScript中的变量是没有类型的。只有值才有。变量可以随时持有任何类型的值。
在对变量执行typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类型,因为JavaScript中的变量没有类型。

var a = 42;typeof a;//"number"a = true;typeof a;//"boolean"//因为typeof 42返回"number"typeof typeof 42;//"string"

2.值

2.1 数组

在JavaScript中,数组可以容纳任何类型的值,可以是字符串、数字、对象(object),甚至是其他数组。

var a = [1,"2",[3]];a.length;//3a[0] === 1;//truea[2][0] === 3;//true

对数组声明后即可向其中加入值,不需要预先设定大小。

var a = [];a.length;//0a[0] = 1;a[1] = "2";a[2] = [3];a.length;//3

使用delete运算符可以将单元从数组中删除,但是要注意,单元删除后,数组的length属性并不会发生变化。

var a = [];a[0] = 1;a[2] = [3];a[1];//undefineda.length;//3

数组通过数字进行索引,但有趣的是它们也是对象,所以也可以包含字符串键值和属性,但这些并不计算在数组长度内:

var a = [];a[0] = 1;a["foobar"] = 2;a.length;//1a["foobar"];//2a.foobar;//2

如果字符串键值能够被强制类型转换为十进制数字的话,它就会被当作数字索引来处理。

var a = [];a["13"] = 42;a.length;//14

建议使用对象来存放键值/属性值,用数组来存放数字索引值。

2.2 字符串

JavaScript中的字符串和字符数组并不是一回事。

var a = "foo";var b = ["f","o","o"];a.length;//3b.length;//3a.indexOf("o");//1b.indexOf("o");//1a;//"foo"b;//["f","o","o"]a[1] = "0";b[1] = "0";a;//"foo"b;//["f","0","o"]

JavaScript中字符串是不可变的,而数组是可变的。
a[1]在JavaScript中并非总是合法语法,正确的方法应该是a.charAt(1)
字符串不可变是指字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。

许多数组函数用来处理字符串很方便(字符串没有这些函数)。

var a = "foo";var b = ["f","o","o"];a.join;//undefineda.map;//undefinedvar c = Array.prototype.join.call(a,"-");var d = Array.prototype.map.call(a,function(v){ ???return v.toUpperCase() + ".";}).join("");c;//"f-o-o"d;//"F.O.O."

2.3 数字

number(数字),包括"整数"和带小数的十进制数。

数字的语法

var a = 0.42;var b = .42;var c = 42.0;var d = 42.;

特别大的特别小的数字默认用指数格式显示。

var a = 5E10;a;//50000000000a.toExponential();//"5e+10"var b = a*a;b;//2.5e+21var c = 1/a;c;//2e-11
var a = 42.59;a.toFixed(0);//43a.toFixed(1);//42.6a.toFixed(2);//42.59a.toFixed(3);//42.590a.toFixed(4);//42.5900a.toPrecision(1);//4e+1a.toPrecision(2);//43a.toPrecision(3);//42.6a.toPrecision(4);//42.59

但是下面的语法是有效的(请注意其中的空格):

2.4 特殊数值

undefined类型只有一个值,即undefined。null类型也只有一个值,即null
null指空值。
undefined指没有值。
null是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。
undefined是一个标识符,可以被当作变量来使用和赋值。

我们通过void运算符即可得到undefined这个值。

var a = 42;console.log(void a, a);//undefined 42

按惯例我们用void 0来获得undefined。void 0、void 1和undefined之间并没有实质上的区别。

特殊的数字

如果数学运算的操作数不是数字类型,就无法返回一个有效的数字,这种情况下返回值为NaN

var a = 2/"foo";//NaNtypeof a === "number";//true

NaN仍然是数字类型。
NaN用于指出数字类型中的错误情况,即“执行数学运算没有成功,这是失败后返回的结果”。

var a = 2/"foo";a == NaN;//falsea === NaN;//false

NaN是一个特殊值,它和自身不相等,是唯一一个非自反的值。
可以使用内建的全局工具函数isNaN(..)来判断一个值是否是NaN。
NaN是JavaScript中唯一一个不等于自身的值。

if(!Number.isNaN){ ???Number.isNaN = function(n){ ???????return n != n; ???};}
无穷数
var a = 1/0;//Infinityvar b = -1/0;//-Infinity

JavaScript的运算结果有可能溢出。
规范规定,如果数学运算的结果超出处理范围,则由IEEE754规范中的“就近取整”模式来决定最后结果。
计算结果一旦溢出为无穷数就无法再得到有穷数。换句话说,就是你可以从有穷走向无穷,但无法从无穷回到有穷。
无穷除以无穷(Infinity/ Infinity)是一个未定义操作,结果为NaN

零值
var a = 0/-3;//-0var b = 0*-3;//-0

加法和减法运算不会得到负零。
根据规范,对负零进行字符串化会返回"0":

var a = 0/-3;a.toString();//"0"a + "";//"0"String(a);//"0"JSON.stringify(a);//"0"+"-0";//-0Number("-0");//-0JSON.parse("-0");//-0
var a = 0;var b = 0/-3;a == b;//true-0 == 0;//truea === b;//true-0 === 0;//true//区分-0和0function isNegZero(n){ ???n = Number(n); ???return (n === 0)&&(1/n === -Infinity);}isNegZero(-0);//trueisNegZero(0/-3);//trueisNegZero(0);//false

特殊的等式

ES6中新加入了一个工具方法Object.is(..)来判断两个值是否绝对相等。

var a = 2/"foo";var b = -3*0;Object.is(a,NaN);//trueObject.is(b,-0);//trueObject.is(b,0);//false

能使用=====时就尽量不要使用Object.is(..),因为前者效率更高,更为通用。Object.is(..)主要用来处理那些特殊的相等比较。

2.5 值和引用

var a = 2;var b = a;//b是a的值的一个副本b++;a;//2b;//3var c = [1,2,3];var d = c;//d是[1,2,3]的一个引用c;//[1,2,3,4]d;//[1,2,3,4]

简单值总是通过值复制的方式来赋值/传递,包括null、undefined、字符串、数字、布尔和ES6中的symbol。
复合值——对象(包括数组和封装对象)和函数,则总是通过引用复制的方式来赋值/传递。

var a = [1,2,3];var b = a;a;//[1,2,3]b;//[1,2,3]b = [4,5,6]a;//[1,2,3]b;//[4,5,6]//由于引用指向的是值本身而非变量,所以一个引用无法更改另一个引用的指向。
function foo(x){ ???x.push(4); ???x;//[1,2,3,4] ???????x = [4,5,6]; ???x.push(7); ???x;//[4,5,6,7]}var a = [1,2,3];foo(a);a;//[1,2,3,4]//我们不能通过引用x来更改引用a的指向,只能更改a和x共同指向的值。
function foo(x){ ???x.push(4); ???x;//[1,2,3,4] ???????x.length = 0; ???x.push(4,5,6,7); ???x;//[4,5,6,7]}var a = [1,2,3];foo(a);a;//[4,5,6,7]/*function foo(wrapper){ ???wrapper.a = 42;}var obj = { ???a : 2};foo(obj);obj.a;//42*//*function foo(x){ ???x = x + 1; ???x;//3}var a = 2;var b = new Number(a);//Object(a)也一样foo(b);console.log(b);//2*/

我们无法自行决定使用值复制还是引用复制,一切由值的类型来决定。

参考资料:《你不知道的JavaScript》(中卷) 第一部分 前两章

JS的类型和值

原文地址:https://www.cnblogs.com/gzhjj/p/9020330.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved