JS的数据类型和访问/流程控制/JSON格式字符串和js对象相互转换
1. JS的数据类型和访问
1.1. 原始类型
JS中的原始数据类型有:
number
,string
,boolean
;声明变量使用
var
关键字.
<script>
/* 数字类型 */
var year = 2020;
/* 字符串类型 */
var name = 'zhangsan';
/* 布尔类型 */
var isUpdate = false;
</script>
- 获取变量的数据类型使用
typeof
. 使用方式:typeof 变量名
.
<script>
var site = 'php.cn';
// 使用typeof来获取变量的数据类型
var dataType = typeof site;
document.write(dataType);
/* result: string */
</script>
1.2 特殊类型
JS中两个特殊的值类型:
null
,undefined
.当只声明变量, 没有初始化变量值时, 此时变量的值是
undefined
. 即,var param;
等效于var param = undefined;
.
<script>
var param;
document.write(param);
/* result: undefined */
var param1 = null;
document.write(param1);
/* result: null */
</script>
- 特别的:
null == undefined
返回的是true
; 而null === undefined
则返回false
<script>
document.write(null == undefined);
/* result: true */
document.write(null === undefined);
/* result: false */
</script>
null
和undefined
的区别:null
表示空对象;undefined
表示非对象类型的变量值为空/无.
<script>
// 获取null的数据类型
var dataType = typeof null;
document.write(dataType);
/* result: object */
</script>
null
/undefined
转换为原始类型数据的值null
/undefined
转换为布尔值, 值转为为false
;
<script>
if (!null) document.write('我被输出了<br>');
if (!undefined) document.write('我被打印了');
/* result:
我被输出了
我被打印了 */
</script>
null
/undefined
转换为字符串时, 值转为:"null"
/"undefined"
.
<script>
document.write(null + '<br>');
document.write(undefined + '<br>');
/* result:
null
undefined */
</script>
null
转为数值时, 值为:0
;undefined
则不能转为数字(输出: NaN).
<script>
document.write(null + 100);
document.write(undefined + 100);
/* result:
100
NaN
*/
</script>
1.3 对象类型: array
, object
, function
- 在js中, 除开
null
和undefined
, 所有数据类型都是对象, 包括原始类型.
<script>
// 证明原始类型数据也是对象: 都能通过他们调用内置方法
var num = 3.1415926;
var name = 'zhangsan';
// 把num的值四舍五入, 保留3位小数
console.log(num.toFixed(3));
console.log(name.toUpperCase());
/* result:
3.142
ZHANGSAN
*/
</script>
1.3.1 数组类型
- JS中的数组跟PHP中的索引数组类似
<script>
// 定义数组
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
document.writeln(player);
/* result: James,Davis,Green,Rondo,Kuzma James */
// 获取数组的中的元素
document.writeln(player[0]);
/* result: James */
</script>
- 判断变量是否为数组类型, 用
Array.isArray(变量名)
, 因为typeof 变量名
的返回值是object
, 不够具体.
<script>
// 定义数组
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
document.writeln('"typeof player" 的值是:' + (typeof player));
document.writeln('变量"player"的值' + (Array.isArray(player) ? '是' : '不是') + '数组');
/* result:
"typeof player" 的值是:object
变量"player"的值是数组
*/
</script>
数组循环
for
循环
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
for (var index = 0; index < player.length; index++) {
document.write(player[index] + ", ");
}
/* result: James, Davis, Green, Rondo, Kuzma, */
</script>
forEach
循环
使用格式:
array.forEach(function(当前遍历到的元素, 当前遍历到的元素在数组中的索引[可选], 受遍历的数组[可选]) {...})
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
player.forEach(function(p, index) {
document.write("第" + (index + 1) + "位出场的是" + p + '<br>');
});
/*
第1位出场的是James
第2位出场的是Davis
第3位出场的是Green
第4位出场的是Rondo
第5位出场的是Kuzma
*/
</script>
数组函数
array.slice
函数用法:
targetArr.slice(起始位置, 结束位置 + 1)
: 获取JS数组中的”起始位置”到”结束为止”之间的元素
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
// 返回前3个球员
document.write(player.slice(0, 3));
/* result : James,Davis,Green */
</script>
array.splice
函数类似PHP中的数组函数
splice
, 可以用它实现对数组元素的增删改.使用语法:
array.splice(起始位置, 元素个数[可选], 替换元素1[可选], 替换元素2[可选]...)
; 其中替换元素1, 替换元素2...
可以以数组的形式传入:[替换元素1, 替换元素2...]
- 实现向当前数组中插入元素:
targetArr.splice(起始位置, 0, 插入元素1, 插入元素2...)
- 实现向当前数组中插入元素:
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
// 在Davis后面插入Bradley, McGee
player.splice(2, 0, ['Bradley', 'McGee']);
document.write(player);
/* result: James,Davis,Bradley,McGee,Green,Rondo,Kuzma */
</script>
- 2. 实现删除当前数组中的元素: `targetArr.splice(起始位置, 元素个数)`
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
// 删除Green, Rondo
player.splice(2, 2);
document.write(player);
/* result: James,Davis,Kuzma */
</script>
- 3. 实现更新当前数组中元素的值: `targetArr.splice(起始位置, 元素个数, 替换后的值1, 替换后的值2[可选]...)`
<script>
var player = ['James', 'Davis', 'Green', 'Rondo', 'Kuzma'];
// 把Davis, Green, Rondo更新为中文名
player.splice(1, 3, ['戴维斯', '格林', '隆多']);
document.write(player);
/* result: James,戴维斯,格林,隆多,Kuzma */
</script>
1.3.2 对象
JS中的对象跟PHP中的关联数组相似.
定义对象
<script>
// 创建对象-1
var player1 = {
name: 'James',
team: '湖人',
age: 35,
// JS中, 如果属性名含有非法字符, 则用双引号 `"` 将其括起来
"player info": {
height: '203',
weight: '113',
position: 'F-G'
}
};
// 以表格的形式打印对象
console.table(player1);
// 另一种定义对象属性的方式见下面的例子
</script>
执行结果:
- 访问对象属性, 有两种方式一种是:
对象名.属性名
; 另一种是类似PHP中的关联数组:对象名[属性名]
. 还有非法字符的属性名, 只能用第二种方式访问.
<script>
// 创建对象-2
var player2 = {};
player2.name = "James";
player2.team = '湖人';
player2.age = 35;
player2["player info"] = {
height: '203',
weight: '113',
position: 'F-G'
};
// 访问对象属性
document.write('姓名:' + player2.name + '<br>');
document.write('球队:' + player2.team + '<br>');
document.write('年龄:' + player2['age'] + '<br>');
document.write('身高:' + player2['player info'].height + '<br>');
document.write('体重:' + player2['player info']['weight'] + '<br>');
document.write('司职:' + player2['player info']['position'] + '<br>');
/*
姓名:James
球队:湖人
年龄:35
身高:203
体重:113
司职:F-G
*/
</script>
遍历对象属性
- 遍历对象方法1: 使用
for 属性名 in 对象
. 语法: for(对象键名 in 对象), 在遍历中, 用对象名["属性名"]
的方式获取元素值更稳一些, 避免出现非法字符遍历报错.
- 遍历对象方法1: 使用
<script>
var player1 = {
name: 'James',
team: '湖人',
age: 35,
// JS中, 如果属性名含有非法字符, 则用双引号 `"` 将其括起来
"player info": {
height: '203',
weight: '113',
position: 'F-G'
}
};
// for...in...遍历对象属性.
for (prop in player1) {
var value = player1[prop];
if (typeof value != 'object')
document.write(prop + ': ' + value + '<br>');
else // 如果属性值是对象, 继续遍历
for (prop1 in value) {
var value1 = value[prop1];
document.write(prop1 + ': ' + value1 + '<br>');
}
}
/* result
name: James
team: 湖人
age: 35
height: 203
weight: 113
position: F-G
*/
</script>
- 遍历对象方法2: 使用
Object.keys(对象)
获取对象的属性名组成的数组, 再借助数组的forEach
进行遍历.
<script>
var player1 = {
name: 'James',
team: '湖人',
age: 35,
// JS中, 如果属性名含有非法字符, 则用双引号 `"` 将其括起来
"player info": {
height: '203',
weight: '113',
position: 'F-G'
}
};
// 获取属性名数组
var props = Object.keys(player1);
props.forEach(function(prop) {
var value = player1[prop];
if (typeof value != 'object')
document.write(prop + ': ' + value + '<br>');
else {
// 如果属性值是对象, 继续遍历
var props1 = Object.keys(value);
props1.forEach(function(prop1) {
var value1 = value[prop1];
document.write(prop1 + ': ' + value1 + '<br>');
});
}
});
/* result:
name: James
team: 湖人
age: 35
height: 203
weight: 113
position: F-G
*/
</script>
</body>
1.3.3 函数
JS中的函数和PHP中的函数类似
JS中的函数类型有:
普通函数
,匿名函数
,立刻执行函数
.- 普通函数:
function 函数名(参数列表) {函数体...}
- 普通函数:
<script>
/* 普通函数 */
function sayHello(name) {
document.write('hello!' + name);
}
sayHello('zhangsan');
/* result: hello!zhangsan */
</script>
- 匿名函数, 又叫函数表达式:
function(参数列表) {函数体...}
; 可以赋值给变量.
<script>
/* 匿名函数 */
var func = function(name) {
document.write('hello!' + name);
}
// typeof 函数的值是function, 不像数组, 返回object
document.write(typeof func);
/* result: function */
// 借助变量使用匿名函数
func('zhangsan');
/* result: hello!zhangsan */
</script>
- 立刻执行函数: 即写完后立刻执行(不用专门调用):
(function(参数列表[可选]) {函数体...})(实参列表[可选])
.
<script>
(function(name) {
document.write('hello! ' + name);
})('lisi');
/* result: hello! lisi */
</script>
2. JS中的流程控制
- JS中的流程控制跟PHP类似
2.1. 流程控制
- 单分支, 就是
if
条件句, 语法:
<script>
if (判断) {
// 判断为true时执行的代码块...
}
</script>
- 双分支, 就是
if...else...
条件句, 语法:
<script>
if (判断) {
// 判断结果为true时执行的代码块
} else {
// 判断结果为false时执行的代码块
}
</script>
多分支, JS中的多分支同样有两种.
- 一种是
if...else if...else...
, 其中else if
可以出现0到多次, 语法:
- 一种是
<script>
if (判断1) {
// 判断1结果为true时执行的代码块
} else if (判断2) {
// 判断1结果为false, 判断2结果为true时执行的代码块
} else if (判断N) {
// 判断(N-1)结果为false, 判断N结果为true时执行的代码块
} else {
// 判断N结果为false时执行的代码块
}
</script>
- 另一种是
switch
语句. 语法:
<script>
switch (变量) {
case 值1:
// do something 1...
break; // 可选
case 值2:
// do something 2...
break; // 可选
case 值N:
// do something N...
break; // 可选
default:
// do something default...
break;
}
</script>
2.2 循环
for
循环
<script>
for(赋值语句; 判断语句; 更新值语句) {
// 循环体, 当判断语句执行结果为true时, 执行循环体中的代码, 否则, 结束循环...
}
</script>
while
循环
<script>
while(判断语句) {
// 循环体, 当判断语句执行结果为true时, 执行循环体中的代码, 否则, 结束循环...
}
</script>
do...while
循环
<script>
do {
// 循环体, 先执行一遍循环体中的代码, 再执行判断, 当判断语句执行结果为true时, 继续执行循环体中的代码, 否则, 结束循环...
} while (判断语句);
</script>
3. JS对象与JSON格式字符串之间的相互转换
3.1 JS对象转换为JSON格式字符串
转换过程, 会忽略JS对象中的这些成员: 方法不会被转换,
undefined
值属性不会被转换, 原型对象成员不会被转换.使用
JSON.stringify()
方法转换.- 使用方法1:
JSON.stringify(JS对象)
, 把对象转换为JSON字符串, 转换所有能转换的成员.
- 使用方法1:
<script>
var player = {
name: 'James',
age: 35,
// 是否自由球员
isFreeAgent: false,
"player info": {
height: 203,
weight: 113,
position: 'F-C'
},
// 退役日期
retireDate: null,
salary: undefined,
// 方法
getName: function() {
return this.name;
}
};
// 转换
var playerStr = JSON.stringify(player);
document.write(playerStr);
/* result: {"name":"James","age":35,"isFreeAgent":false,"player info":{"height":203,"weight":113,"position":"F-C"},"retireDate":null} */
</script>
- 使用方法2:
JSON.stringify(JS对象, 需转换的属性数组)
, 只转换参数2指定的属性.
<script>
var player = {
name: 'James',
age: 35,
// 是否自由球员
isFreeAgent: false,
"player info": {
height: 203,
weight: 113,
position: 'F-C'
},
// 退役日期
retireDate: null,
salary: undefined,
// 方法
getName: function() {
return this.name;
}
};
// 只转换name, age
var playerStr = JSON.stringify(player, ['name', 'age']);
document.write(playerStr);
/* result: {"name":"James","age":35} */
</script>
- 使用方法3:
JSON.stringify(JS对象, function(遍历到的对象的属性名, 遍历到的对象的属性值))
, 遍历属性进行转换过程中, 使用参数2指定的回调函数先处理遍历到的属性值, 然后再对其进行转换; 有点类似PHP中的数组函数array_walk
.
<script>
var employee = {
name: 'zhangsan',
depart: '开发部',
sex: 'female',
age: 25,
isMarried: false,
hireDate: '2020-01-01',
fireDate: null,
salary: 8888
};
var empStr = JSON.stringify(employee, function(prop, value) {
switch (prop) {
case 'salary':
return '保密';
break;
// 函数内部可以调用外部变量, 直接拿employee来用
case 'age':
return employee['sex'] == 'female' ? '女孩的年龄不要猜' : value;
break;
// 不希望转换的属性, 返回undefined即可
case 'hireDate':
return undefined;
break;
default:
return value;
}
});
document.write(empStr);
/* result: {"name":"zhangsan","depart":"开发部","sex":"female","age":"女孩的年龄不要猜","isMarried":false,"fireDate":null,"salary":"保密"} */
</script>
JSON.stringify()
的第三个参数, 是格式化json数据对象用的, 无关功能.
<script>
var employee = {
name: 'zhangsan',
depart: '开发部',
sex: 'female',
age: 25,
isMarried: false,
hireDate: '2020-01-01',
fireDate: null,
salary: 8888
};
var empStr = JSON.stringify(employee, function(prop, value) {
return value;
}, 4);// 第三个参数值为4, 表示在属性前面添加4个空格
console.log(empStr);
/*
{
"name": "zhangsan",
"depart": "开发部",
"sex": "female",
"age": 25,
"isMarried": false,
"hireDate": "2020-01-01",
"fireDate": null,
"salary": 8888
}
*/
</script>
3.2 JSON格式字符串转换为JS对象
- 使用
JSON.parse(JSON字符串)
函数
<script>
// 在js中, 可以通过在行末增加\来把字符串换行
var empStr = '{\
"name": "zhangsan",\
"depart": "开发部",\
"sex": "female",\
"age": 25,\
"isMarried": false,\
"hireDate": "2020-01-01",\
"fireDate": null,\
"salary": 8888\
}';
// jsonStr => JS obj
var empObj = JSON.parse(empStr);
for(prop in empObj) {
document.write(eprop + ': ' + empObj[prop] + '<br>');
}
/*result:
name: zhangsan
depart: 开发部
sex: female
age: 25
isMarried: false
hireDate: 2020-01-01
fireDate: null
salary: 8888
*/
</script>
JSON.parse(JSON字符串, function(prop, value) {...})
: 可以给第二个参数传入一个回调函数, 把回调函数处理后的属性值作为转换后的JS对象的属性值.
<script>
// 在js中, 可以通过在行末增加\来把字符串换行
var empStr = '{\
"name": "zhangsan",\
"depart": "开发部",\
"sex": "female",\
"age": 25,\
"isMarried": false,\
"hireDate": "2020-01-01",\
"fireDate": null,\
"salary": 8888\
}';
// jsonStr => JS obj
var empObj = JSON.parse(empStr, function(prop, value) {
// 薪水保密
if(prop == 'salary') {
return '****';
}
return value;
});
for(prop in empObj) {
document.write(eprop + ': ' + empObj[prop] + '<br>');
}
/*result:
name: zhangsan
depart: 开发部
sex: female
age: 25
isMarried: false
hireDate: 2020-01-01
fireDate: null
salary: ****
*/
</script>
学习心得
数据类型和访问, 流程控制是每一门变成语言都有的内容, 无他, 必须记住. JS对象和JSON字符串之间的转换, 非常重要, 因为很多网站前后端的数据交互都是使用JSON数据. 将JS对象转换为字符串, 才能把前端数据发送到服务端(还可以用序列化的方式); 而服务端返回的JSON数据, 也需要经过转换成JS对象后, 才能渲染到模板中.