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);