JS基础(二)运算符、流程控制语句、数组对象、JSON对象、Date对象、Math对象、Function对象(包括JS预编译)
一 运算符
<script>
// 算数运算符
// (1) 自加运算
var x = 10;
// x = x + 1;
// x += 2;
var ret = x++; // 先赋值再计算: x += 1
// var ret = ++x; //先计算再赋值: x += 1
console.log(x);
console.log(ret);
// (2) 比较运算
console.log(1 == "1"); // TRUE
console.log(1 === "1"); // FALSE 不允许JS做任何暗转换,必须严格相等
// (3) 逻辑运算符
console.log(Boolean(3>2 && 2===1));
console.log(Boolean(3>2 || 2===1));
console.log(Boolean(!3>2));
// (4) 短路运算
console.log(1 && 2);
console.log(3 || 2);
console.log(0 && 2);
console.log(0 || 5);
// (5) 三元运算符
var age =2;
var ret = age>=18?"成年":"未成年";
console.log(ret)
</script>
二 流程控制语句
python中是用缩进,
if 条件:
缩进的内容
JS中不是,像Java。
<script>
/*
// if分支分支
// 双分支语句
if(表达式){
}else{
}
// 多分支语句
if(表达式){
}else if(表达式){
}else if(表达式){
}else if(表达式){
}else{
}
// switch分支语句
*/
var user = "root";
var pwd = "12";
if(user === "root" && pwd === "123"){
console.log("登录成功!")
}else {
console.log("登录失败!")
}
var score = 86;
if (score>90){
console.log("成绩优秀!")
}else if(score>80){
console.log("成绩良好!")
}else if(score>60){
console.log("成绩及格!")
}else{
console.log("成绩不及格!")
}
// switch语句
var weekend = 3;
switch (weekend) {
case 1:console.log("星期一");break;
case 2:console.log("星期二");break;
case 3:console.log("星期三");break;
case 4:console.log("星期四");break;
case 5:console.log("星期五");break;
case 6:console.log("星期六");break;
case 0:console.log("星期日");break;
default:console.log("无效数字!");break;
}
</script>
三 数组对象
<script>
// 数组的声明两种方式
var arr01 = [12,"hello",true];
console.log(arr01,typeof arr01); // "object"
var arr02 = new Array(12,"hello",true);
console.log(arr01,typeof arr02);
console.log(arr01.length);
// 数组的方法
// var arr = [1,2,3,4,5];
// 1 插入和删除
// arr.push("a");
// arr.push([111,222]);
// console.log(arr);
// var ret = arr.pop();
// console.log(ret);
// console.log(arr);
// arr.unshift(100);
// console.log(arr);
// arr.shift();
// console.log(arr);
// 2 反转和排序
// var arr02 = [1,4,3,6,2];
// var arr02 = [1,4,10,6,2,100];
// arr02.reverse();
// console.log(arr02);
/*function sort_num(a,b){
return a-b
}
arr02.sort(sort_num);
console.log(arr02);*/
// splice方法
var arr = [1,2,3,4,5];
// (1)删除多个元素
// arr.splice(2,2);
// console.log(arr);
// (2) 添加多个元素
// arr.splice(2,0,100,101,102);
// console.log(arr);
// (3) 替换多个元素
// arr.splice(2,2,33,44);
// console.log(arr);
var arr1 = [1,2,3];
var arr2 = [4,5,7];
var ret = arr1.concat(arr2);
console.log( ret );
// join方法
var s = "zhangsan li wangwu";
var ret = s.split(" ");
console.log(ret);
var s2 = ret.join("-");
console.log(s2);
console.log(arr1.includes(2));
console.log(arr1.indexOf(3));
console.log(Array.isArray(arr1));
// 切片操作
arr3 = [111,222,333,444,555,666];
console.log(arr3.slice(1,3));
console.log(arr3.slice(1,-1));
console.log(arr3.slice(1));
console.log(arr3.slice());
console.log(arr3.slice(-3,-2));
console.log(arr3.slice(-2,-3)); // []
// 数组循环
for (var i=0;i<arr3.length;i++){
// 循环体
console.log(i,arr3[i])
}
</script>
四 JSON对象
JSON是JavaScript的对象表示法(JavaScript Object Notation),轻量级的数据交换格式,易于阅读和编写。
json中的成员如果是键值对,键名必须是字符串,而json中的字符串必须使用双引号圈起来。
前端项目中,一般使用json作为配置文件。
json可以让语言之间进行通信,易于数据传输。
JS序列化和反序列化:
<script>
var s = '{"name":"bj","age":20}'
// 把一个json字符串解析成JS能识别的数据类型:反序列化
var data = JSON.parse(s);
console.log(data,typeof(data)) //{"name":"bj","age":20} object类型
// 把JS的数据类型转换成json字符串:序列化
var res = {
state:true,
data:[123,234,456]
};
var res_json = JSON.stringify(res)
console.log(typeof(res)) // object
console.log(res_json,typeof(res_json)) // {"state":true,"data":[123,234,456]} string
</script>
五 Date对象
六 Math对象
<script>
// Number对象内置方法
// tofix(*) 保留小数位
var num = 3.1415926
console.log(num.toFixed(2)) //3.14
// Math对象内置方法
// abs()绝对值
console.log(Math.abs(num))
// ceil()向上取整
console.log(Math.ceil(num))
// floor()向下取整
console.log(Math.floor(num))
// max(*,*,*...)
// min()
// pow(x,y) x的y次方,等于2**3
console.log(Math.pow(2,3));
console.log(2**3)
//random() 生成0-1随机数
//random()*10 生成0-10随机数
</script>
七 Function对象
函数在程序中代表的就是一段具有功能性的代码,可以让我们的程序编程更加具有结构性和提升程序的复用性,也可以让代码变得更加灵活强大。
1. 声明函数
函数的定义方式1:
function 函数名(参数){
函数体;
return 返回值;
}
功能说明:可以使用变量、常量或者表达式作为函数调用的参数,函数关键字function定义。
函数名的定义规则与标识符一致,大小写是敏感的,返回值必须用return。
函数的定义方式2:
用Funcion类直接创建函数,语法如下:
var 函数名 = new Function("参数1","参数2",...);
虽然由于字符串的关系,第二种定义形式写起来有点复杂,但有助于理解函数不过就是一种引用类型,它的行为与用Function类明确创建函数行为是相同的。
2. 函数调用
3. 函数参数
形参实参:
function foo(x,y){
console.log("x:",x);
console.log("y:",y);
}
foo(1,2,3) // js很宽松,不会报错
foo(1) // 不报错 y: undefined
默认参数:
比如 function stu_info(name,gender="male"){ }
arguments 参数:
function add(){
console.log("arguments:",arguments);
var ret = 0 ;
for(var i in arguments){
ret += arguments[i];
}
return ret;
}
console.log(add(1,2,3,4))
4. 匿名函数
匿名函数,即没有名字的函数,在实际开发中使用的频率非常高,也是学号js的重点。
注意:使用匿名函数表达式时,函数的调用语句,必须放在函数声明语句之后。
使用普通函数,因为预编译的关系,调用语句可以放在函数声明之前。
<script>
// 匿名函数的调用方式1:
var foo = function (){
console.log("匿名函数")
}
foo();
// 匿名函数的调用方式2:
(function(){
console.log("匿名函数")
})();
// 实例
(function(x,y){
console.log(x+y)
})(1,2);
// 高阶函数
function bar(){
return function(){
console.log("inner函数")
}
}
</script>
5. 函数作用域
作用域是js最重要的概念之一。要理解js作用域和作用域的工作原理。
任何程序设计语言都有作用域的概念,作用域就是变量的可访问范围,控制着变量与函数的可见性和生命周期,在js中,变量的作用域有全局作用域和局部作用域,
局部变量,在函数内部声明,它的生命周期在当前函数被调用的时候,当函数调用完毕后,内存中自动销毁当前变量;
全局变量,在函数外部声明,它的生命周期在当前文件中被声明以后就保存在内存中,直到当前文件执行完毕以后,才会在内存销毁掉。
6. JS预编译
首先一道面试题:等学完再回来看
var num3 = 10
function func2(){
console.log(num3);
var num3 = 20
}
func2();
console.log(num3);
js运行三个阶段:
- 语法分析
- 预编译
- 解释执行
语法分析就是js引擎去检查代码是否有语法错误,解释执行就是执行代码。预编译简单理解就是在内存中开辟一些空间,存放一些变量与函数。
预编译分为全局预编译和局部预编译。
- 在js脚本加载之后,会先检查是否存在低级错误;
- 在语法检查完成后,开始全局预编译;
- 在全局预编译之后,就解释一行,执行一行;
- 在执行到函数调用那一行的前一刻,会先进行函数预编译,再往下执行。
全局预编译的三个步骤:
- 创建GO对象(Global Object),即Windows对象;
- 找变量声明,将变量名作为GO属性名,值为undefined;
- 查找函数声明,作为GO属性,值赋予函数体。
局部预编译的四个步骤:
- 创建AO对象(Activation Object),执行上下文;
- 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined;
- 将实参值和形参统一;
- 在函数体里面找函数声明,值赋予函数体。
案例:
<script>
var a = 10;
console.log(a);
function foo(a) {
console.log(a);
var a = 100;
console.log(a);
function a() {
}
console.log(a);
var b = function () {
};
console.log(b);
function d() {
}
}
var c = function () {
console.log("匿名函数C");
};
console.log(c);
foo(20);
</script>
全局预编译:(一定小心c匿名函数,和标准函数声明是不一样的,不是作为函数变量,根本上是作为一个变量赋值)
G0/window = {
a: undefined,
c: undefined, // c是匿名函数,和标准函数声明是不一样的,不是作为函数变量,根本上是作为一个变量赋值
foo: function (a) {
console.log(a);
var a = 123;
console.log(a);
function a() {
}
console.log(a);
var b = function () {
}
console.log(b);
function d() {
}
}
}
解释执行代码(直到执行调用函数foo(20)语句):
Go / window = {
a: 10,
c: function () {
console.log("匿名函数c");
},
foo: function (a) {
console.log(a);
var a = 123;
console.log(a);
function a() {
}
console.log(a);
var b = function () {
}
console.log(b);
function d() {
}
}
}
调用foo(20)之前发生的局部预编译:
// 局部预编译前两步
AO = {
a: undefined,
b: undefined,
}
// 局部预编译第三步
AO = {
a: 20, //这里值是等于实参
b: undefined,
}
// 局部预编译第四步
AO = {
a: function a() {
},
b: undefined,
d: function d() {
},
}
最终运行的结果(有一点没懂捏):
var a = 10;
console.log(a); // 10
function foo(a) {
console.log(a); // function c(){} ?这里有点晕
var a = 100;
console.log(a); //100
function a() { //这个是局部预编译开辟空间用的,没有做什么,所以打印的a还是100
}
console.log(a); // 100
var b = function () {
};
console.log(b); // 空函数体 function b(){}
function d() {
}
}
var c = function () {
console.log("匿名函数C");
};
console.log(c);
foo(20);
浙公网安备 33010602011771号