一. JavaScript逻辑运算符
1.1 if语句
基本语法结构
if (/* 条件表达式 */) {
// 执行语句
}
if (/* 条件表达式 */){
// 成立执行语句
} else {
// 否则执行语句
}
if (/* 条件1 */){
// 成立执行语句
} else if (/* 条件2 */){
// 成立执行语句
} else if (/* 条件3 */){
// 成立执行语句
} else {
// 最后默认执行语句
}
大致就是判断语句,条件成立时应该做什么,不成立时做什么
简化if语句可以使用三元运算符
表达式1 ? 表达式2 : 表达式3
判断表达式1是否成立,成立则执行表达式2,不成立则执行表达式3
1.2 switch语句
语法格式
switch (expression) {
case 常量1:
语句;
break;
case 常量2:
语句;
break;
case 常量3:
语句;
break;
…
case 常量n:
语句;
break;
default:
语句;
break;
}
break可以省略,如果省略,代码会继续执行下一个case
switch 语句在比较值时使用的是全等操作符, 因此不会发生类型转换(例如,字符串’10’ 不等于数值10)
1.3 循环控制语句
1.3.1 while语句
基本语法
// 当循环条件为true时,执行循环体,
// 当循环条件为false时,结束循环。
while (循环条件) {
//循环体
}
代码示例
/*
* 循环
* while循环
* 语法:
* while(布尔表达式) {
* //循环要做的事情
* }
* 要求: 布尔表达式的值为true则执行,否则结束
* */
console.log("Hello World!");
let i = 1;/*声明计数器*/
while (i <= 20) {
console.log("Hello World!" + i);
i++;
}
console.log("********************************")
let s = 1;
while (s <= 20) {
s++;
console.log("Hello World!" + s);
}
1.3.2 do…while循环
do…while循环和while循环非常像,二者经常可以相互替代,但是do…while的特点是不管条件成不成立,都会执行一次。
do…while和while循环的不同点
- while先判断条件,后执行操作,条件不成立则一次不执行
- do-while先执行一次,后判断条件,条件不管是否成立,至少都会执行一次
/*
* do-while循环
* do {
* //要做的事情,先做一次,再根据表达式的结果决定是否重复来做
* } while(表达式);
*
* */
let index = 1;
do {
console.log("你好世界" + index);
index++;
}while (index <= 20);
1.3.3 for循环
while和do…while一般用来解决无法确认次数的循环。for循环一般在循环次数确定的时候比较方便
for循环基本语法
// for循环的表达式之间用的是;号分隔的,千万不要写成,
for (初始化表达式1; 判断表达式2; 自增表达式3) {
// 循环体4
}
执行顺序
1243----243 -------243(直到循环条件变成false)
- 初始化表达式
- 判断表达式
- 自增表达式
- 循环体
<script>
/*
* for(表达式1; 表达式2; 表达式3){
* 循环体(4)
* }
* 执行顺序
* 第一次执行:1243
* 后续执行顺序243,243,243直到条件不成立
* */
/*使用for循环输出1-100的值*/
// for (let i = 1; i <= 100; i++) {
// console.log(i);
// }
/*
*
* 所有的for循环都可以改写成while循环,反之不一定
* for循环用来处理确定次数的循环,while循环用来改写不确定次数的循环
*
* */
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum/100);
for (let index = 100; index <= 999; index++) {
let x = parseInt(index / 100);
let y = parseInt((index % 100) / 10);
let z = parseInt(index % 10);
let t = Math.pow(x,3) + Math.pow(y,3) + Math.pow(z,3);
if (t === index) {
console.log(index);
}
}
</script>
双层for循环案例
<script>
// for (let i = 0; i <= 5; i++) {
// console.log("第一层for循环的第" + i + "次");
// for (let j = 0; j <= 5; j++) {
// console.log("第二层for循环的第" + j + "次");
// }
// }
/*外层执行一次,里层执行五次*/
let sum = '';
for (let i = 1; i <= 9; i++) {
for (let j = 1; j <= i; j++) {
sum += j + '*' + i + '=' + i*j + '\t';
}
sum += "\n";
}
console.log(sum);
let sum1 = '';
for (let i = 1; i <= 9; i++) {
for (let j = 1; j <= i; j++) {
sum1 += '*';
}
sum1 += '\n';
}
console.log(sum1);
/*使用*打印9行的直角三角形*/
let sum2 = '';
for (let i = 9; i >= 1; i--) {
for (let j = 1; j <= i; j++) {
sum2 += "*";
}
sum2 += "\n";
}
console.log(sum2);
</script>
1.4 continue和break
break:立即跳出整个循环,即循环结束,开始执行循环后面的内容(直接跳到大括号)
continue:立即跳出当前循环,继续下一次循环(跳到i++的地方)
1.5 数组
1.5.1 数组概念
所谓数组,就是将多个元素(通常是同一类型)按一定顺序排列放到一个集合中,那么这个集合我 们就称之为数组。
数组是一个有序的列表,可以在数组中存放任意的数据,并且数组的长度可以动态的调整。
1.5.2 创建数组
- 声明即赋值的方式
/*声明即赋值的方式*/
let arr = [1,3,5,7,9,'张三',false];
console.log(arr.toString());
- 只声明不赋值
/*只声明不赋值*/
let arr2 = new Array();
创建数组代码案例
// 创建一个空数组
var arr1 = [];
// 创建一个包含3个数值的数组,多个数组项以逗号隔开
var arr2 = [1, 3, 4];
// 创建一个包含2个字符串的数组
var arr3 = ['a', 'c'];
// 可以通过数组的length属性获取数组的长度
console.log(arr3.length);
// 可以设置length属性改变数组中元素的个数
arr3.length = 0;
获取数组
// 格式:数组名[下标] 下标又称索引
// 功能:获取数组对应下标的那个值,如果下标不存在,则返回undefined。
var arr = ['red',, 'green', 'blue'];
arr[0]; // red
arr[2]; // blue
arr[3]; // 这个数组的最大下标为2,因此返回undefined
遍历数组
<script>
let arr = [1,2,3,4,6,7,8,3,2,10];
/*遍历输出数组中所有的值*/
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
/*数组求和*/
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += parseInt(arr[i]);
}
console.log(sum);
let arr2 = ['a','b','c','d','e'];
let s = '';
for (let i = 0; i < arr2.length; i++) {
if (i === arr2.length - 1) {
s += arr2[i];
}else {
s += arr2[i] + '-';
}
}
console.log(s);
/*把arr3中所有的0去除,组成新数组*/
let arr3 = [1,5,0,8,6,0,4,0,3,0,0,2];
let arr4 = [];
for (let i = 0; i < arr3.length; i++) {
if (arr3[i] === 0) {
continue;
}
arr4.push(arr3[i]);
}
console.log(arr3.toString());
console.log(arr4.toString());
</script>
数组新增元素
// 格式:数组名[下标/索引] = 值;
// 如果下标有对应的值,会把原来的值覆盖,如果下标不存在,会给数组新增一个元素。
var arr = ["red", "green", "blue"];
// 把red替换成了yellow
arr[0] = "yellow";
// 给数组新增加了一个pink的值
arr[3] = "pink";
// 向数组末尾增加一个gray的值
arr.push("gray");
二. JavaScript函数
2.1 函数解释
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数,起个名字(函数名),在后续开发中可以反复调用
函数的作用就是封装一段代码,将来可以重复使用
函数就是方法,方法就是函数
2.2 函数定义
- 函数声明(命名函数)
/*声明式函数-----命名函数*/
function show() {
console.log("我是eason");
}
- 函数表达式
var fn = function() {
// 函数体
}
- 特点
函数声明的时候,函数体并不会执行,只要当函数被调用的时候才会执行。 函数一般都用来干一件事情,需用使用动词+名词,表示做一件事情 tellStory sayHello 等
2.3 函数调用
- 调用函数的语法
函数名();
- 特点
函数体只有在调用的时候才会执行,调用需要()进行调用,可以重复多次调用
/*函数名()的方式调用,可以调用多次*/
show();
/*求1-100的和*/
function getSum() {
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
getSum();
getSum();
2.4 函数的参数
基本语法
// 函数内部是一个封闭的环境,可以通过参数的方式,把外部的值传递给函数内部
// 带参数的函数声明
function 函数名(形参1, 形参2, 形参...){
// 函数体
}
// 带参数的函数调用
函数名(实参1, 实参2, 实参3);
- 形式参数
- 在声明一个函数的时候,为了函数的功能更加灵活,有些值是固定不了的, 对于这些固定不了的值。我们可以给函数设置参数。这个参数没有具体的值,仅仅起到 一个占位置的作用,我们通常称之为形式参数
- 实际参数
- 如果函数在声明时,设置了形参,那么在函数调用的时候就需要传入对应的 参数,我们把传入的参数叫做实际参数
案例代码
<script>
/*某个需求功能相同,但是数值可能不同*/
/*方法的括号内声明的变量,称为参数,不得使用任何关键字,我们称之为形参,该变量只在本方法内有效*/
/*求1-100的和*/
// function getSum(num) {
// let sum = 0;
// for (let i = 1; i <= num; i++) {
// sum += i;
// }
// console.log(sum);
// }
/*调用方法时括号内给的值表示传递参数进入函数,我们称之为实参*/
// getSum(100);
// getSum(200);
function test(num) {
console.log(num);
}
test(123456);
function getSum(min,max) {
if (min > max) {
[min,max] = [max,min];
}
let sum = 0;
for (let i = min; i <= max; i++) {
sum+=i;
}
console.log(min + "-" + max + "的值是:" + sum);
}
/*调用多个参数的函数时,多个实参用英文逗号隔开*/
getSum(1,230);
/*调用函数传参时,传递的参数类型决定了形参的类型*/
getSum('a','b');
getSum(23,1);
</script>
输出结果
4.5 arguments的使用
JavaScript中,arguments对象是比较特别的一个对象,实际上是当前函数的一个内置属性。也就是说所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有的实参。 arguments是一个伪数组,因此及可以进行遍历
arguments对象就是存储了所有传递的实际参数
<script>
function f1() {
/*函数内部有一个专门的参数列表对象来存储所有的实参,arguments*/
/*arguments是伪数组,他有数组的特性,但是不是数组*/
console.log(arguments);
console.log("我没有参数!");
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
f1(1,2,'abcdefg');
function getSum() {
let sum = 0;
for (let i = 0; i < arguments.length; i++) {
sum+=arguments[i];
}
console.log(sum);
}
getSum(1,5,4,847,1,23,5456,78,1);
</script>
4.6 函数类型
4.6.1 匿名函数
匿名函数:没有名字的函数
匿名函数必须先声明出来后再调用,否则会报错
将匿名函数赋值给一个变量,这样就可以通过变量进行调用 匿名函数自调用
执行匿名函数的作用:防止全局变量污染。
let f2 = function () {
console.log("我没名字,我也自豪!");
}
f2();
上面就是匿名函数的基本语法格式
4.6.2 自调用函数
匿名函数不能通过直接调用来执行,因此可以通过匿名函数的自调用的方式来执行
<script>
let f1 = function () {
console.log("大家好,我是匿名函数!");
}
f1();
f1();
f1();
/*匿名函数自调用--------只能执行一次*/
/*
* 绝对性匿名,保证只会执行一次,并55且不会被别人污染
* */
(function () {
console.log("写完就让我说话吧!");
})();
/*命名函数*/
function f2() {
console.log("我是命名函数!")
}
f2();
let num3 = 10;
console.log(num3);
/*输出表示函数的变量名或者函数名,得到的结果是这个函数自身---自身代码*/
/*输出函数代码*/
console.log(f1);
/*没有return返回值,就输出undefined*/
console.log(f1());
console.log(f2);
(function (num) {
console.log(num);
})(5);
</script>
4.6.3 函数是一种数据格式
- 函数作为参数
- 因为函数也是一种类型,可以把函数作为一两个函数的参数,在两一个函数中调用
- 函数作为返回值
- 因为函数是一种类型,所以可以把函数可以作为返回值从函数内部返回,这种用法在后面很常见。
function fn(b) {
var a = 10;
return function () {
alert(a+b);
}
}
fn(15)();
4.7 预解析
JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。JavaScript解析器执行
JavaScript代码的时候,分为两个过程:预解析过程和代码执行过程
变量预解析过程分析
1. 变量的预解析会提升变量的声明到当前作用域的最前面,赋值操作不会
2. 函数的预解析会提升函数的声明到当前作用域的最前面,调用操作不会
3. var的优先级高于function,意思就是预解析后变量在函数前面
4. 这里面的讨论与let无关,因为let不能声明重复的变量值,var可以声明重复的变量值
5. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
6. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
7. 先提升var,在提升function
var num1 = 20;
function f1() {
console.log(num1);
var num1 = 10;
// console.log(num1);
}
// console.log(f1);
f1();
//函数内部预编译的结果
var num1 = 20;
function f1() {
var num1;
console.log(num1);
num1 = 10;
}
这段代码运行的时候会输出undefined,因为函数内部再预编译的时候只有声明的时候提升了,而赋值并没有提升,所以输出的时候只有一个为赋值的变量
4.8 作用域
作用域:变量可以起作用的范围
- 全局作用域
- 声明变量时不适应任何关键字修饰(谨慎使用) 定义:num = 3
- 在任何地方都可以访问到的变量就是全局变量,对应全局作用域
- 局部作用域
- 只在固定的代码片段内可访问到的变量,最常见的例如函数内部。对应局部作用域(函数作用域)
- 使用let声明的变量(ES6可用)
- 函数作用域
- 使用var声明的变量
- 整个函数内有效,不分内外侧
作用域定义
- 函数外声明的变量可以在函数内使用
- 函数内声明的变量不能再函数外使用
- 想要使用函数内声明的变量,需要用到全局变量(隐式全局变量----不使用任何关键字声明的变量,应该在调用函数后生效)
- 作用域向内传递
- var声明的变量叫做函数的作用域,整个函数内有效,不分内外侧
- ES6引入的新概念: 局部作用域,let声明的变量叫做局部作用域,只在一组大括号内有效,只会在内传递,不会向外传递
4.8.1 作用域链
只有函数可以制造作用域结构, 那么只要是代码,就至少有一个作用域, 即全局作用域。凡是代码中有函数,那么这个函数就构成另一个作用域。如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域。
将这样的所有的作用域列出来,可以有一个结构: 函数内指向函数外的链式结构。就称作作用域链。
作用域链: 有层级关系的函数,内部调用变量
如果不存在,向上一层寻找,一直寻找到顶层
<script>
/*
* 作用域链: 有层级关系的函数,内部调用变量
* 如果不存在,向上层寻找,一直到顶层
*
* var声明的变量叫做全局变量
* 没有任何关键字声明的变量叫做隐式全局变量
* */
let num1 = 5;
function f1() {
f2();
console.log(num);
function f2() {
function f3() {
num = 10;
console.log(num1);
}
f3();
}
}
f1();
</script>
三. 总结
以上就是这两天学习的内容,这两天主要还是对JavaScript的基础知识进行学习,这两天对JavaScript的语法和Java语法进行了对比,很像,但一些细节的差异性还是挺大的,这篇博文里面的内容最重要的就是需要掌握JavaScript的预解析的概念,这个概念大概就是像对于优先级的判断,预解析的时候变量的声明总会被提高到当前作用域的最前面,但是变量赋的值却不会提高,而是保留在原地。
不仅仅是需要掌握JavaScript的函数预解析思想,还要掌握JavaScript的作用域,三大作用域:全局作用域,局部作用域和函数作用域,以及根据什么关键字如何赋予不同的作用域都需要掌握。
以上便是这篇博文的全部内容,明天开始会对于JavaScript的对象进行讲解,本人为刚开始学习前端的一名小白,博文有些观点可能与实际会有一些偏差,大家看后发现有什么不对的可以多多指正,大家一起学习,共同进步!!!