js中有八种数据类型
数据类型Number,String,Boolean,Undefined,Null,symbol,bigInt
复杂数据类型Object

typeof 操作符
由于js中的变量是松散类型的,所以它提供了一种检测当前变量的数据类型的方法,也就是typeof关键字.
typeof 123 //Number
typeof 'abc' //String
typeof true //Boolean
typeof undefined //Undefined
typeof null //Object
typeof { } //Object
typeof [ ] //Object
typeof console.log() //Function
注意一点:NaN 是 Number 中的一种,非Number 。
NaN是Number 中的特殊数值
1、假设: Number('as') == NaN ?
肯定是false, Number(‘as’) 输出 NaN。
注)用 isNaN()检测是否是非数值型。
请注意这里 isNaN 帮我转成 true 。
期间我一直在纠结 Number(‘as’) 输出 NaN ?NaN == NaN 为什么是 false。其实 js 规定的NaN 不等于NaN。
isNaN(123)//false
isNaN('123')//false
isNaN('123ab')//true
isNaN(Number(‘as’) )//true
2、假设:Number('123') == NaN ?
肯定是false,Number('123’) 输出 123。
null类型进行typeof操作符后,结果是object,原因在于,null类型被当做一个空对象引用。
检测数组类型的方法
1. instanceof
var arr=[1,2];console.log(arr instanceof Array)//true
var arr=12;console.log(arr instanceof Array)//false
2. 对象的 constructor 属性
var arr=[1,2];console.log(arr.constructor === Array)//true
var arr=12;console.log(arr.constructor === Array)//false
3.Array.isArray( ) 检验值是否为数组
var arr=[1,2];console.log(Array.isArray(arr) )//true
var arr=12;console.log(Array.isArray(arr))//false
JS数据类型:null 和 undefined 有什么区别?
Null 只有一个值,是 null。不存在的对象。
Undefined 只有一个值,是undefined。没有初始化。undefined 是从 null 中派生出来的。
简单理解就是:undefined 是没有定义的,null 是定义了但是为空。
JS数据类型:null 不存在的原因是什么?如何解决?
不存在的原因是:
1、方法不存在
2、对象不存在
3、字符串变量不存在
4、接口类型对象没初始化
解决方法:
做判断处理的时候,放在设定值的最前面
JS数据类型:== 和 === 有什么区别,什么场景下使用?
== 表示相同。
比较的是物理地址,相当于比较两个对象的 hashCode ,肯定不相等的。
类型不同,值也可能相等。
=== 表示严格相同。
例:同为 null/undefined ,相等。
简单理解就是 == 就是先比较数据类型是否一样。=== 类型不同直接就是 false。
JS数据类型:对象可以比较地?
对象是可以比较,遍历比较key 和 value就行, Object.is(value1, value2)。
1.Number类型
Number类型包含整数和浮点数(浮点数数值必须包含一个小数点,且小数点后面至少有一位数字)两种值。
NaN:非数字类型。特点:① 涉及到的 任何关于NaN的操作,都会返回NaN ② NaN不等于自身。
isNaN() 函数用于检查其参数是否是非数字值。
isNaN(123) //false isNaN("hello") //true
2.String类型
字符串有length属性。
字符串转换:转型函数String(),适用于任何数据类型(null,undefined 转换后为null和undefined);toString()方法(null,defined没有toString()方法)。
3.Boolean类型
该类型只有两个值,true和false
4.Undefined类型
只有一个值,即undefined值。使用var声明了变量,但未给变量初始化值,那么这个变量的值就是undefined。
var a;console.log(a===undefined)//true;
5.Null类型
null类型被看做空对象指针,前文说到null类型也是空的对象引用。
6.Object类型
js中对象是一组属性与方法的集合。这里就要说到引用类型了,引用类型是一种数据结构,用于将数据和功能组织在一起。引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。
7、 Symbol 类型(es6 新增)
Symbol 类型的对象永远不相等,即便创建的时候传入相同的值。因此,可以用解决属性名冲突的问题(适用于多少编码),做为标记。
Symbol 指的是独一无二的值。每个通过 Symbol() 生成的值都是唯一的。
symbol 是一种基本数据类型(primitive data type) 。Symbol()函数会返回symbol类型的值,该类型具有静态属性和静态方法。它的静态属性会暴露几个内建的成员对象;它的静态方法会暴露全局的symbol注册,且类似于内建对象类,但作为构造函数来说它并不完整,因为它不支持语法:“new Symbol()”。
每个从Symbol()返回的symbol值都是唯一的。一个symbol值能作为对象属性的标识符;这是该数据类型仅有的目的。
let var_symbol = Symbol();
let other_symbol = Symbol();
console.log(var_symbol === other_symbol);
// false
console.log(typeof var_symbol);
// symbol
console.log(var_symbol.constructor === Symbol)
// true
那么,如何使用 Symbol 创建两个可以相等的变量呢?
let var_symbol = Symbol.for('symbol');
let other_symbol = Symbol.for('symbol');
console.log(var_symbol === other_symbol)
// true
Symbol.for(key) 方法会根据给定的键 key(字符串),来从运行时的 symbol 注册表中找到对应的 symbol,如果找到了,则返回它,否则,新建一个与该键关联的 symbol,并放入全局 symbol 注册表中。
————————————————————————————————————————————
和 Symbol() 不同的是,用 Symbol.for() 方法创建的的 symbol 会被放入一个全局 symbol 注册表中。Symbol.for() 并不是每次都会创建一个新的 symbol,它会首先检查给定的 key 是否已经在注册表中了。假如是,则会直接返回上次存储的那个。否则,它会再新建一个。
8、BigInt 类型(ES10新增)
解决number数值超出精度问题
js中number类型只能安全的表示-9007199254740991(-(2^53-1))
和9007199254740991((2^53-1)) 任何超出此范围的整数值都可能失去精度。
如:
console.log(9999999999999999999)//10000000000000000000
console.log( 9007199254740995 ); // 9007199254740996
console.log( 9007199254740995n ); // 9007199254740995n
Javascript 中的任意精度整数,可以安全存储和操作大整数。即始超出 Number 能够表示的安全整数范围。是 chrome 67中的新功能。
BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数。而在其他编程语言中,可以存在不同的数字类型,例如:整数、浮点数、双精度数或大斐波数。
JavaScript 所有数字都保存成 64 位浮点数,这给数值的表示带来了两大限制。一是数值的精度只能到 53 个二进制位(相当于 16 个十进制位),大于这个范围的整数,JavaScript 是无法精确表示的,这使得 JavaScript 不适合进行科学和金融方面的精确计算。二是大于或等于2的1024次方的数值,JavaScript 无法表示,会返回Infinity。
// 超过 53 个二进制位的数值,无法保持精度
Math.pow(2, 53) === Math.pow(2, 53) + 1 // true
// 超过 2 的 1024 次方的数值,无法表示
Math.pow(2, 1024) // Infinity
ES2020 引入了一种新的数据类型 BigInt,来解决这个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。
为了与 Number 类型进行区分,BigInt 类型的数据必须添加后缀n。
12 // 普通Number
12n // BigInt
// BigInt 的运算
1n + 2n // 3n
111111111111111111111111111111111111111111111111111111n+1n
//111111111111111111111111111111111111111111111111111112n
0.1n+0.2n//报错;不能用小数;只能整数
// 与Number 类型进行运算
1 + 1n // Uncaught TypeError
BigInt 与普通整数是两种值,它们之间并不相等。
12n === 12 // false
由于 BigInt 与 Number 完全属于两种类型,并且不会进行隐式转换,所以没有办法进行混合运算。想要运算的话,必须将两种数据类型转换为同一张后,方可进行计算:
BigInt(number) // 将一个 Number 转换为 BigInt
Number(bigint) // 将一个 BigInt 转换为 Number
typeof 运算符对于 BigInt 类型的数据返回 bigint。
typeof 12n // 'bigint'
由于 BigInt 并不是一个构造函数,所以,不能使用 new BigInt() 的方式来构建实例;
另外,当你创建一个 BigInt 的时候,参数必须为整数,否则或报错
new BigInt()
// Uncaught TypeError: BigInt is not a constructor at new BigInt
BigInt(1.2)
// Uncaught RangeError: The number 1.2 cannot be converted to a BigInt because it is
BigInt使用方式:
10n + 20n; // → 30n
10n - 20n; // → -10n
+10n; // → TypeError: Cannot convert a BigInt value to a number
-10n; // → -10n
10n * 20n; // → 200n
20n / 10n; // → 2n
23n % 10n; // → 3n
10n ** 3n; // → 1000n
9007199254740992 === 9007199254740993; // → true 居然是true!
BigInt不支持一元加号运算符, 这可能是某些程序可能依赖于 + 始终生成 Number 的不变量,或者抛出异常。另外,更改 + 的行为也会破坏 asm.js代码
因为隐式类型转换可能丢失信息,所以不允许在bigint和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由BigInt或Number精确表示
BigInt可以正常地进行位运算,如|、&、<<、>>和^
元素都为BigInt的数组可以进行sort
三大引用类型
1.Object类型
我们看到的大多数类型值都是Object类型的实例,创建Object实例的方式有两种。
第一种是使用new操作符后跟Object构造函数,如下所示
var person = new Object();
person.name = "Micheal";
person.age = 24;
第二种方式是使用对象字面量表示法,如下所示
var person = {
name : "Micheal",
age : 24
};
2.Array类型
数组的每一项可以用来保存任何类型的数据,也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象....另外,数组的大小是可以动态调整的。
创建数组的基本方式有两种
第一种是使用Array构造函数,如下所示
var colors = new Array("red","blue","yellow");
第二种是使用数组字面量表示法,如下所示
var colors = ["red","blue","yellow"];
3 Function类型
每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数通常是使用函数声明语法定义的,如下所示
function sum(num1,num2){
return num1 + num2;
};
这和使用函数表达式定义函数的方式相差无几。
var sun = function (){
return sum1 + sum2;
};
也就是说,js按照存储方式分为值类型和引用类型。那么他们的计算有什么区别呢?
题目1: var a = 100;
var b = a;
a = 200;
console.log (b);
题目2: var a = {age : 20};
var b = a;
b.age = 21;
console.log (a.age);
题目1的答案是 100,题目2的答案是21,
题目1是简单的值类型,在从一个变量向另一个变量赋值基本类型时,会在该变量上创建一个新值,然后再把该值复制到为新变量分配的位置上。
此时,a中保存的值为 100 ,当使用 a 来初始化 b 时,b 中保存的值也为100,但b中的100与a中的是完全独立的,该值只是a中的值的一个副本,此后,
这两个变量可以参加任何操作而相互不受影响。也就是说基本类型在赋值操作后,两个变量是相互不受影响的。
题目2是引用类型,当从一个变量向另一个变量赋值引用类型的值时,同样也会将存储在变量中的对象的值复制一份放到为新变量分配的空间中。
这时保存在变量中的是对象在堆内存中的地址,所以,与简单赋值不同,这个值的副本实际上是一个指针,而这个指针指向存储在堆内存的一个对象。那么赋值操作后,
两个变量都保存了同一个对象地址,则这两个变量指向了同一个对象。因此,改变其中任何一个变量,都会相互影响。
因此,引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
网友评论