JavaScript数据类型及存储和转换
1. 数据类型分类
数据类型
- 基本(原始)类型:Number、String、Boolean、Null、Undefined
- 引用(对象)类型:Object(Array、Date、Function等)
判断数据类型
typeof+操作数 返回值:字符串
typeof 1 //'number'
typeof 'a'//'string'
typeof a12//'undefined'
typeof true//'boolean'
typeof null//'object'
数据变量和类型
- JavaScript中变量没有类型
- JavaScript中数据值有类型
- 变量可以随时持有任何类型的值
- 对变量执行typeof操作得到结果是该变量持有的值的类型
var a='3';
console.log(typeof a);//string
例题
- 遍历person对象中所有属性代码并在控制台输入对应属性值
//创建person对象
var person={
name:'lily',
age:20,
singing:function(){
console.log('singing');
},
playing:function(){
console.log('playing');
}
}
//遍历person对象中属性值及其对应的类型
for(var key in person){
console.log(person[key],typeof(person[key]));
}
//分别遍历person对象中属性和方法极其对应的具体的值
for(var key in person){
if(typeof(person[key]!='function')){
console.log('属性值',person[key]);
}
else{
console.log('方法',person[key]);
}
}
- 判断变量存储的值
function Student(name,age){
this.name=name;
this.age=age;
}
var stu=Student('lily',18);//对象创建的函数模式 需要new调用Student
console.log(stu);//undefined
console.log(typeof stu);//undefined
//正确调用↓
var stu =new Student('lily', 18);
console.log(stu);//stu对象
console.log(typeof stu);//Object
2. 数据类型存储
变量声明:声明指向某一块用来保存数据
变量赋值:在声明的内存中用于存放数据
堆栈内存
-
栈内存
- 存储值大小固定
- 系统自动分配内存空间
- 空间小、运行效率高
-
堆内存
- 存储值大小不定,可动态调整
- 由程序员通过代码进行分配
- 空间大,运行效率相对较低
基本类型与引用类型的区别
-
内存分配方式不同
- 基本数据类型临时变量分配在栈区
- 引用数据类型临时变量分配在堆区
- 基本数据类型临时变量分配在栈区
-
访问机制不同
- 基本类型值直接访问
- 引用类型值通过引用访问,不能直接访问——从栈区获得地址引用,再在堆区中找到对应的值
-
变量赋值不同
- 基本类型相互独立互不影响
- 引用类型赋值
- 基本类型相互独立互不影响
var a={x:10,y:20};
var b=a;
b.x=5;
console.log(a.x);//5
//通过第二步var b=a;使得变量名保存在栈区的b的对象访问地址指向a的访问地址
//此时a,b指向同一块堆区的空间
//后续通过b.x=5操作 改变a,b共同指向堆区的x的值为5
//所以改变b中的x值时,获取的a中x值也同时发生改变
//此时a,b仍旧指向同一块内存,打印输出a的x时其值也变成5
-
比较变量不同
- 基本类型比较
var a=20;
var b=20;
a===b;//true
a=b;
a===b;//true
var a={x:10,y:20};
var b={x:10};
a.x==b.x;//true 引用类型的基本类型变量值比较
- 引用类型比较
var a={x:10,y:20};
var b={x:10,y:20};
a==b;//false 引用类型指向内存空间不同
a===b;//false
a=b;//将a的堆区的内存空间指向b所对应的内存空间
a===b;//true 此时两者指向相同内存空间 比较结果相同
-
参数传递
- 基本类型值:数据值传给参数,之后变量参数互不影响;初始化何值,打印时仍旧何值
- 引用类型值:把对象的引用值传递给参数,参数与对象指向同一对象,相互影响;且将原来指向堆区的空间改变
//例1
function foo(num,obj){
num=2;
obj.value='hello world';
}
var num1=10;
var obj1={
value:'hello';
}
foo(num1,obj1);
console.log(num1);//10
console.log(obj1);//'hello world'
//例2
var a=[1,2,3,4];//数组为引用类型
var b=a;//将变量b指向和a同样的堆区内存空间
b.shift();//将b内存中第一个元素弹出
console.log(a);//[2,3,4]由于b发生变化 所以a的内存空间也对应发生变化
console.log(typeof(a));//Object 引用类型
//例3
//此题着重注意 第一次做错
var obj1={value:'111'};
var obj2={value:'222'};
function change(obj){
obj.value='333';//①
obj=obj2;//②
return obj.value;
}
var foo=change(obj1);
console.log(foo);//222
console.log(obj1.value);//333
//change函数调用obj1 修改obj1在堆区的指向空间值由111变为333 ;
//后又将obj1指向obj2 此时返回obj1的value值已经变成222
//foo为调用该函数的返回值 即obj1的value值为222
//由于执行②后已经断开 所以obj1的实际value值为333
使用值 | 使用引用 | |
赋值 | 实际赋值的是值,存在两个不同的、独立的副本 | 赋值的只是对数值的引用。如果通过这个新的引用修改了数值,这个改变对原始引用也可见 |
比较 | 比较两个独立的值 | 比较两个引用,以判断引用是否为同一个数值 |
传递 | 传递给函数的值是独立的副本,对其改变在函数外部无影响 | 传递给函数对数值的引用。函数传递修改数值,其改变在函数外部也可见 |
3. 数据类型转换
-
转换为Number:与数字进行运算结果是数字类型
- undefined——>NaN
- null——>0
- 字符串:空串变为0;数字字符串直接取数字(省略开头结尾空格)
-
强制转换
- parseInt()强制转换为整型
- parseFloat()强制转换为浮点型
- Number()强制转换为数字类型
-
NaN是数字类型的一种 表示不正确的数 自身与自身不相等
- isNaN()判断是否为没有意义的值 返回值为布尔值 是没有意义的数返回值为true 正常的数字则返回值为false
-
undefined与undefined是相等的
-
转换为 String
- String() 强制类型转换 或者 + “ ” 拼接运算
var a = 1;
var b = "2";
var c = 3;
console.log(a + b + c);/* 123 */
console.log(a + c + b);/* 42 */
console.log(b + c + a);/* 231 */
- 转换为Boolean类型
var a;
console.log(a + 1);/* NaN */
console.log(!a + 1);/* 2 */
console.log(!!a + 1);/* 1 */
//!!
var a;
var b = a * 0;/* NaN */
if (b == b) {
console.log(b * 2 + "2" - 0 + 4);
} else {
console.log(!b * 2 + "2" - 0 + 4);/* 26 */
}
//!b*2为2 数字类型2加上字符串类型"2"变为"22"
//"22"-0又转换为数字类型22 后续22+4=26}
- undefined——》false
- null——》false
- 数字 0,NaN——》false ; 其他数字——》true
- 字符串:空串——》0 其他字符串1
- **强制转化**Boolean()
typeof(Infination);//Number
//字符串类型+加号==>字符串拼接
var a=2;
var b='3';
var c=a+b;
console.log(c,typeof c);//23 string
var a=2;
var b=String(a);
console.log(a,typeof(a));//2 Number 基本类型传递对其本身无影响
console.log(b,typeof(b));//string
var a;/* 声明但未定义 即为undefined */
if (a == a) {/* undefined与undefined是相等的 */
console.log(a * 1);/* undefined转换为number类型即为NaN 返回值仍为NaN */
} else {
console.log(a + 1);}
typeof(Infination);//Number
//js实现轮播图实现方法1
<img src="images/1.jpg" id="img">
<script>
var img = document.getElementById('img');
var index = 1;
setInterval(function () {
img.src = "images/" + index + ".jpg"; //注意这里 是img的src属性的值在变 所以这里是img.src="" 而不是img.innerHtml=""
index++;
if (index > 4) {
index = index % 4;
}
}, 1500);
//js实现轮播图实现方法2
<img src="images/img_1.jpg" alt="">
<script>
var img = document.getElementsByTagName('img')[0];
var index = 1;
setInterval(function () {
index %= 5;
index += 1;
if (index == 6) {
index = 1;
}
img.src = "images/img_" + index + ".jpg"
}, 1500);