JS学习计划

概念
JavaScript (简称"JS") 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言.
JavaScript 是一门脚本编程语言。
JavaScript 是一门弱类型编程语言。
var a = "字符串"
var b = 布尔值
b = 数字
Java 是强类型编程语言。
string a = "字符串"
int b = 100
boolean c = true
运行环境
1. 浏览器 (客户端)
2. Nodejs
作用
1.可以实现用户与界面交互的逻辑(开关、下拉菜单、轮播图、列表渲染、条件渲染、滚动加载等)
2.可以处理数据的前后端交互 ajax (网络请求)
3.可以搭建web服务、处理后端的业务逻辑 nodejs (登录、注册、找回密码、发送邮件验证、数据持久化)
创建一个helloworld
<button onclick="show()">点击按钮执行JS</button>
<script type="text/javascript">
// 1) 内嵌JS
// 在页面上输出一个hello world
// document.write("<h1> hello world 1</h1>");
// document.write("<h1> 你好 世界 1</h1>");
</script>
<script src="./01_helloworld.js"></script>
<script>
// 3) 编写函数
function show(){
document.write("<h1> hello world 3 </h1>");
document.write("<h1> 你好 世界 3 </h1>");
}
// 单行注释
/*
*
*
* 多行注释
*
*
*/
</script>
<!--
综上所述:
1. 搞清楚JS可以写在哪里(书写)
2. 注释在JS中可以怎么写
3. script 就是脚本的意思
type:类型(h5中默认就是在script标签中编写脚本)
-->
ECMAScript (基础)
1、 数据、数据类型
// 数据:是指设备、浏览器可以识别的内容。
'abc'// 带引号的是字符串,浏览器可以识别为字符串数据类型。
// efg // 不带引号, 这efg字母浏览器不能识别。
// 报错:ReferenceError: efg is not defined (引用类型的错误)
// 数据类型有很多种
// 1) 字符串类型 (带引号的是字符串,注意是英文标点符号)
'abc';
"efg";
`ijk`;
// 2) 数字类型 (0~9)
123;
// 3) 布尔值 (true, false)
true ;
false;
// 4) 未定义 (缺少值)
undefined ;
// 5)空 (表示不需要有值)
null
// ; 分号是分隔符; 可以表示代码结束的意思。
2、 控制台输出(以后可以这种方式排查代码)
// 可以使用console.log()函数
// 在控制台检查代码是否执行,检查变量是否有值。
// console 日志,是对象
// console.log(变量) log函数调用
console.log(1); // 1
console.log(2); // 2
console.log(3); // 3
// JS正常执行顺序是从上往下执行
console.log("abc");// 'abc'
console.log(100);// 100
console.log(true);// true
// 通过console.log()这个函数可以在控制台上看数据的输出、打印
// 可以观察数据、代码执行、变量是否有值
3、typeof 语句
// 使用typeof语句检测数据类型
// 因为 typeof 可以返回数据类型的单词(这是单词字符串),typeof 返回的字符串,通过这个单词可以知道数据所属类型
console.log(typeof 100);// 'number' 数字类型
console.log(typeof 'abc');// 'string' 字符串类型
console.log(typeof true );// 'boolean' 布尔类型
console.log(typeof undefined );// 'undefined' 未定义 (缺少值)
console.log(typeof null );// 'object' (特殊类、单独记忆) 空对象的意思,不需要有值
console.log(typeof function(){});// 'function' 函数类型 函数中的大括号表示代码块
console.log(typeof {}) ;// 'object' 对象
console.log(typeof []) ;// 'object' 数组 检测数组[] 返回的也是object。 以及可以使用其他方法检查
// Array.isArray([])// true 返回结果是true表示这是数组的意思。
4、变量、声明变量
//变量:是指储存数据的容器,它的值可以改变
//变量用于记录数据的
var a = 1
a = 2
a = 3
//记录年龄
var age; // 声明一个age变量 (告诉浏览器中内存中有一个叫age的容器)
console.log(age);// undefined 因为没有给它进行赋值,但不会报错,因为var关键做声明(定义)
// 记录数量100
var num = 100;
console.log(num);
// = 等于号表示赋值,把100赋值给num变量的意思
// 在等于号的右边加做值、数据。
// var 是ES5(第五个JS版本)语法
console.log(sex);// 可以输出什么? undefined
// 此处的undefined是变量声明提升的意思。名称提升了(内存中有), 值没有提升(没值)。
// 意思是不用先引用后声明
var sex = "男";//
// 先声明后使用
console.log(sex);// '男'
// 总结:
// 1、要理解变量是什么?
// 2、var 关键子有什么用
// 3、注意先声明后引用,不然就出现undefined(缺少值)
5、关键字、保留字、命名规范
// 变量: 是指存储数据的容器。
// 在JS第五个版本中,我们是采用var关键字声明变量(定义变量)
var userName = "小明";// 声明了userName变量,并且赋值为“小明”
// 告诉浏览器在内存中有一个叫 userName 的存储容器,这个容器里面的数据是“小明”
var $ = "函数";//是正确的命名
var $btn = "函数";//是正确的命名
var _ = "JS";//是正确的命名
var _btn = "JS";//是正确的命名
var 年龄 = 100;//是正确的命名
var 性别 = "男";//是正确的命名
console.log(年龄);// 100
// 变量的命名规范:
// 1. 不能使用关键字或保留字作为变量名称
// 2. 可以使用英文词汇、或者拼音命名 user age sex address (yonghu,nianling,xingbie,dizhi)
// 3. 可以使用驼峰命名 loginButton userPassword loginButtonIndex
// 4. 可以使用下划线 login_button user_passowrd login_button_index
// 5. 不能使用特殊符号命名除了 $ 和 _ 。例如:!~@#%……&*-
// 6. 可以使用中文命名,但是不推荐使用
6、运算符
// 1) 算术运算符
// console.log(1 + 1);// 2
// console.log(1 - 1);// 0
// console.log(1 * 1);// 1
// console.log(1 / 1);// 1
// console.log(12 % 10);// 取余数2
// ++ 自增一
// var a = 10;
// console.log( a ++ );// 10 先输出,后运算
// console.log( a );// 11
// var b = 10;
// console.log( ++ b);// 11 先运算,后输出
// console.log(b);// 11
// -- 自减一
// var c = 10;
// console.log( c --); // 10
// console.log( c --); // 9
// console.log( c ); // 8
// var d = 10;
// console.log( -- d);// 9
// console.log( d);// 9
// 换种写法:
// var e = 10;
// console.log(e += 10);// 20 e + 10
// console.log(e -= 5);// 15 e - 5
// 总结:
// ++、-- 运算符在变量之前,表示先运算,后输出。否则,先输出,后运算。
// 2) 比较运算符
// > 大于号
// >= 大于等于
// < 小于号
// <= 小于等于
// == 等等于 (判断值是否相等)
// === 等等于 (判断值是否相等和数据类型是否相等)
// != 不等于
// console.log(1 < 2);// true
// console.log(3 < 2);// false
// console.log(3 == 2);// false
// console.log(3 == "3");// true (值相等,隐式转换,意思是浏览器自动转换)
// console.log(3 === "3");// false (3: number类型 "3": 字符串类型)
// console.log(1 != 2);// true
// console.log(2 != 2);// false
// 3) 逻辑运算符
// || “或” 表示条件两个或者以上,只要有一个条件成立(真的),结果就成立(是真)
// console.log( true || false);// true
// console.log( true || false || false || false);// true
// console.log( false || false || false || false);// false
// console.log( 1 < 2 || 2 > 3 || 3 > 4 || 4 > 5);// true
// var v1 = true || false;
// console.log(v1);// true
// var v2 = false || true;
// console.log(v2);// true
// var v3 = "" || "hello world";// 前者没有值,就把后者的值赋给变量
// console.log(v3);// 'hello world'
// var v4 = undefined || 123;
// console.log(v4);// 123
// && “且” “与” 表示条件两个或者以上,只要有一个条件不成立(是假),结果就不成立(是假)
// console.log(true && false);// false
// console.log(true && false && true && true);// false
// console.log(true && true && true && true);// true
// console.log(1 < 2 && 3< 4 && 4 < 5 && 5 < 6);// true
// var k1 = true && false;
// console.log(k1);// false
// var k2 = false && true;
// console.log(k2);// false
// var k3 = true && true;
// console.log(k3);// true
// var k4 = true && 100;// 前者有值为true, 选择把后者的值赋给变量
// console.log(k4);// 100
// 4) 取反运算符 ! (取相反的值) 非 !
// console.log(true);// true
// console.log(!true);// false
// console.log(!false);// true
// console.log(!100);// false (100 可以表示有值,有值表示true, 在true前面加叹号表示取相反的值)
// 5) 赋值运算符 (1一个等于号)
// var user = "admin";
// console.log(user);//'admin'
7、标点符号
// ; 表示代码结束,分割的意思
var a ;
var b ;
var c ;
// , 表示代码继续,没有结束的意思
var h , m , s ;
// = 表示赋值
var hour = 20;
// ! 非, 取反
var isShow = !true;
console.log(isShow);// false
// . 引用,连接
console.log("test");
// ''
// ""
// ``
// 这些引号括着的内容表示字符串
// ()
var v = (1 + 2) * 3;
console.log(v);// 9
// 关于JS中的标点符号,注意它们是英文的标点符号。
8、JS表达式、三元运算符表达式 (三目运算符)
//JS表达式: 一行代码
//var a = 100
// 1 > 0
//条件判断表达式
//三元运算符表达式
//条件是否成立 ? 执行代码1 : 执行代码2
//if语句写法
//if(条件成立) {执行代码1} else {执行代码2}
//例如
//定义变量记录小时
var h = 7;
var hour = h < 10 ? '0'+h : h
console.log(hour) //07
//示例
1 > 2 ? console.log("条件成立") : console.log("条件不成立")
9、判断语句
// 判断语句
// if 语句
// if else 语句
// if else if else if else... 语句 (多个条件判断)
// 1) 定义变量记录一个分数,小于60分,在控制台上输出 “成绩不及格”
var score = 56;
if(score < 60) {// 符合条件的情况下,就进入执行 {} 中代码
console.log("成绩不及格");
}
// 2) 定义变量记录一个分数,大于等于60分,在控制台上输出 “成绩及格”,否则,输出“成绩不及格”。
var result = 40;
if(result >= 60) {
// 符合条件,执行if作用域 {} 的代码
console.log("成绩及格");
} else {
// 否则,执行else作用域 {} 的代码
console.log("成绩不及格");
}
// 3) 定义变量记录一个分数,根据以下给出的参数做判断
// 基础很差 0 ~ 39
// 基础差 40 ~ 59
// 基础好 60 ~ 79
// 基础很好 80 ~ 100
// 未知分数
var value = 65;
if(value >= 0 && value <= 39) {
console.log("基础很差");
}
else if(value >= 40 && value <= 59){
console.log("基础差");
}
else if(value >= 60 && value <= 79) {
console.log("基础好");
}
else if(value >= 80 && value <= 100) {
console.log("基础很好");
}
else {
console.log("未知分数");
}
10、控制流语句
// 定义方向变量 (上up 下down 左left 右right)
var direction = "right";
// 控制流语句(分支处理)
// switch(变量) { case 分支1: 执行代码1; break; case 分支2: 执行代码2; break;}
switch(direction){
// 分支1
case "right":
// 符合条件,执行代码
console.log("蛇往右移动")
break;
// 分支2
case "left":
console.log("蛇往左移动")
break;
case "up":
console.log("蛇往上移动")
break;
case "down":
console.log("蛇往下移动")
break;
// 默认,否则
default :
console.log("未知方向....")
break;
}
// 总结:
// 控制流语句,也是用于做判断的,可以使用 if else if 语句代替。
11、循环语句
// 循环: 重复执行、不断执行。
// 可以通过循环语句,重复执行console.log()代码
// 循环语句:
// for(){} 语句
// while(){} 语句
// do {} while() 语句
// for in 语句
// for of 语句
// for(代码1; 代码2; 代码3){ 循环体 }
// 首先执行代码1,执行代码2,然后进入循环体,走出循环体,最后执行代码3
//例如
for (var i = 1; i < 11; i++){
console.log(i)
}
// 循环就是重复执行的意思
// 可以减少重复的、冗余的代码。
// 代码1: 初始化一个值
// 代码2: 条件判断,符合条件就会进入循环体 (条件要合理,否则出现死循环)
// 代码3: 控制值改变
for(var num = 10; num > 5 ; num --){
console.log("数字:", num);
}
------------作业练习-------------
渲染文件夹中的图标(循环+字符串拼接)

100imgs
https://download.csdn.net/download/lw134482/89609475
答案
var imgs = "<div>"
for (var i=1 ; i<=100;i++){
imgs += `<span><img src="../../lesson/day03/源代码/icon-assets/${i}.bmp" alt=""></span>`
}
imgs += "</div>"
document.write(imgs)
---------------------------------------------------------------------------------------------------------------------------------
12、基本数据类型
// 基本数据类型(ES5)
// 1) 字符串 string 类型 (小写字母的string单词 代表数据类型 浏览不能直接识别)
// 2)数字 number 类型
// 3)布尔值 boolean 类型
// 4) undefined 缺少值 (尚未存在)
// 5)null 空 (不应该有值)
console.log(typeof 'abc');// 'string'
console.log(typeof 123);// 'number'
console.log(typeof true);// 'boolean'
console.log(typeof undefined);// 'undefined'
console.log(typeof null);// 'object' 空指针对象 (没有值)
13、数据类型转换
1.显式转换
// 转换数据类型:
// 一、调用函数
// String (大写字母的String 单词 代表的是构造函数 浏览器可以识别)
// Number
// Boolean
// String() 在一个单词的尾部添加小括号这种写法是什么意思? 答案: 表示调用函数
// String(数据) 表示调用函数并且传递参数的意思。
// 1) 转字符串
// console.log(typeof true);// 'boolean'
// console.log(typeof 100);// 'number'
// console.log(typeof String(100));// 'string'
// console.log(typeof String(true));// 'string'
// console.log(typeof String('abc'));// 'string'
// console.log(typeof String(abc));// 报错 ReferenceError: abc is not defined (引用类型错误)
// 2)转数字类型
// console.log(typeof "abc");// 'string'
// console.log(Number("abc"));// NaN (not a number) 非数字 特殊的数值。
// console.log(typeof Number("abc"));// 'number'
// console.log(typeof "100");// 'string'
// console.log(Number("100"));// 100
// console.log(typeof Number("100"));// 'number'
// 3) 转布尔值类型
// console.log(Boolean(100));// true
// console.log(Boolean(1));// true
// console.log(Boolean(0));// false (0 等同于 false)
// console.log(Boolean(-1));// true
// console.log(Boolean("abc"));// true
// console.log(Boolean(""));// false ('' 等同于 false)
// console.log(Boolean(undefined));// false (undefined 等同于 false)
// 4) 把内容解析成字符串
// var num = 2024;// 2024
// console.log(typeof num);// 'number'
// var str = num.toString();// '2024' 把数字解析成字符串。
// console.log(typeof str);// 'string'
// toString() 还有另一个作用,进行进制转换。
// 0123456789abcdef
// var v1 = 11;
// console.log(v1.toString(16));// b
// 5)把字符串解析成数字(更多是指以数字字符开头的字符串)
// parseInt 把字符串解析成整型(整数不带小数点)
// parseFloat 把字符串解析成浮点型(带小数点)
// CSS 属性
// margin-left: 100px
// width: 100px
// height: 100px
// padding: 100px
var v2 = "100px";// 字符串
console.log(parseInt(v2));// 100 数字
console.log(typeof parseInt(v2));// 'number'
console.log(parseInt("px100"));// NaN (遇到不是数字开头的字符串,解析的结果为NaN)
console.log(parseInt("100.11px"));//100
var v3 = "50.55px";
console.log(parseFloat(v3));// 55.55 数字
console.log(typeof parseFloat(v3));// 'number'
console.log(parseFloat("px50.55"));// NaN (遇到不是数字开头的字符串,解析的结果为NaN)
2.隐式转换
// 二、隐式转换 (浏览器自动转换)
// 1) 转字符串类型
// 任意数据类型和字符串拼接,都会变成字符串类型
// + 这个加号运算符(加法运算、字符串拼接)
// console.log(10 + 20);// 30
// console.log(10 + "abc");// '10abc'
// console.log(typeof 10 );// 'number'
// console.log(typeof 10 + "abc");// 'numberabc'
// console.log(typeof (10 + "abc"));// 'string'
// console.log(typeof true);//'boolean'
// console.log(typeof (true + ""));//'string'
// console.log(typeof (undefined + ""));//'string'
// 2) 转数字类型
// 主要数字字符串使用这个“-”可以隐式转换成数字类型
// 任何数字减去0都等于其本身
// 任何数字乘以1都等于其本身
// - 这个符号号运算符(减法运算、转数字)
// console.log(100 - 60);// 40
// console.log(typeof "100");// 'string'
// console.log(typeof ("100" - 0));// 'number'
// console.log(typeof ("100" * 1));// 'number'
// 3)两个等于号表示比较值的大小,不比较数据类型
// ==
// 0 == false
// "" == false
// 1 == true
console.log(0 == false); // true
console.log("" == false); // true
console.log(0 == ""); // true
console.log(1 == true); // true
console.log(undefined == false); // false
// 条件判断(以下条件判断均为false/不执行代码)
if(false) {
console.log("执行代码1");
}
if(0) {
console.log("执行代码2");
}
if(undefined) {
console.log("执行代码3");
}
if("") {
console.log("执行代码4");
}
if(null) {
console.log("执行代码5");
}
14、日期对象
日期对象: Date
函数属于引用数据类型。
Date 这是一个函数
console.log(typeof Date);// 'function'
这个 Date对象(函数) 需要通过new操作符来调用
new Date() 代表创建Date的实例对象
这个实例对象就是 {方法1,方法2,方法3} 通过这些方法可以获取关于日期、关于时间的信息。 // 好比如,获取年份、月份、日期、星期、小时、分钟、秒钟、毫秒钟、时间戳等
var dt = new Date()
// dt 是日期实例(具体数据集合) {方法1,方法2,方法3,....... }
//年份
var year = dt.getFullYear()
console.log(year)
//月份 (因为month是从0开始 0~11 所以month+1才是实际的月份)
var month = dt.getMonth()
console.log(month)
//日期
var date = dt.getDate()
console.log(date)
//星期 (星期天为0~星期六6)
var week = dt.getDay()
console.log(week)
//小时
var hour = dt.getHours()
console.log(hour)
//分钟
var minute = dt.getMinutes()
console.log(minute)
//秒钟
var second = dt.getSeconds()
console.log(second)
//毫秒 (1秒=1000毫秒)
var ms = dt.getMilliseconds()
console.log(ms)
//时间戳 (指从1970-01-01 00:00:00 至今的总毫秒值)
var time = dt.getTime()
console.log(time)
15、数学对象
数学对象: Math
Math 这个对象不是函数哦~~ 不需要new操作符调用,它可以直接使用
Math.xxxx() 表示调用数学对象提供的方法的意思。
关于数学里面数字的处理
// 1)取整数
// 2)取绝对值
// 3)随机数
// 4)平方/立方
//向上取整(不带小数点)
console.log(Math.ceil(100.02)) //101
console.log(Math.ceil(100.01)) //101
//向下取整
console.log(Math.floor(100.02)) //100
console.log(Math.floor(90.02)) //90
//四舍五入取整
console.log(Math.round(100.4)); //100
console.log(Math.round(100.5)); //10
//取绝对值(正数)
console.log(Math.abs(-100)); //100
console.log(Math.abs(-55)); //5
//平方/立方
console.log(Math.pow(2,2)); //2*2 = 4
console.log(Math.pow(2,3)); //2*2*2 = 8
console.log(Math.pow(5,3)); //5*5*5 = 125
console.log(Math.pow(2,4)); //2*2*2*2 = 1
//随机数
console.log(Math.random()); //0-1 之间随机小数
console.log(Math.random()*10); //0-10 之间随机小数
//获取两个数之间都随机数 Math.random()*(最大值 - 最小值) + 最小值;
console.log(Math.random()*(50-20)+20); //20-50之间随机小数
//获取随机整数
var num = Math.random() * 30 + 20
console.log(Math.floor(num)); //20-50之间随机整数
16.函数
1.认识函数
// 函数:是指可以实现特定功能的代码块。(可以重复利用的代码块)
// 封装函数 关键字 function
// 步骤:
// 1)定义函数 function foo(){
console.log("-----日常生活---------")
console.log("起床")
console.log("吃早餐")
console.log("回家睡觉")
console.log("----------------------") }
// 2)调用函数 foo();
// 总结:
// 函数是什么? 函数是可以重复使用的代码块
// function 是定义函数的关键字 . function 函数名称() { }
// 函数作用域,代码可执行的环境 { 重复执行的代码 }
// 函数必须要调用,代码块才能执行 // 弄清楚函数怎么定义、怎么调用
2.怎么定义函数
// 1) 关键字 function (推荐)
// 之前
sayHello();
// 定义函数
function sayHello() {
console.log("hello world.");
}
// 之后
sayHello();
// 2) 关键字 var (推荐)
// 把代码块赋值给变量
// function(){} 代码块
// 之前 (不能在var声明之前调用)
// console.log(sayHello2);// undefined
// sayHello2(); // TypeError: sayHello2 is not a function
// 把函数赋值给变量
var sayHello2 = function () {
console.log("说,你好");
}
// 之后
sayHello2();
// 3) 关键字 var 和 构造函数 (函数表达式)
// sayHello3();// 报错,类型错误
// 不推荐使用
var sayHello3 = new Function("console.log('不说,你好')");
sayHello3();
// 构造函数: 由new操作符调用的函数,我们叫做构造函数。
3.函数作用域
作用域: 指代码可执行的环境。
console.log('test');
在全局环境下定义的变量,叫做全局变量(共享)
var num = 100;
console.log('1.0:', num);
function f() {
console.log('2.0:', num);
}
f();
我们找到window对象(全局对象),我们检查这个对象下有没有num的属性。
挂在window对象上的数据都是全局的
console.log(window);
函数作用域:代码块可执行的环境 { }
定义函数
function foo() {
局部变量(私有)
var count = 99;
console.log("3.0", count);
}
function boo() {
局部变量(私有)
var count = 98;
console.log("4.0", count);
}
调用函数
foo();
boo();
console.log(count); 报错,ReferenceError: count is not defined
因为全局环境下 根本就没有count这个变量
总结
1、作用域是指代码可执行的环境
2、在全局环境下声明的变量是全局变量,是可以被共享的
3、在函数作用域环境下声明的变量是局部变量。是私有的
4、window是全局对象,把数据挂在这个对象下,可以全局使用
5、变量要先声明,后引用
4.函数返回值
函数返回值:就是调用完函数返回的结果。
return 语句,只能在函数作用域中使用,不能直接在全局环境下使用
写在return后的数据就是返回值
return 100; //报错,SyntaxError: Illegal return statement
报个语法错误
1) 定义函数,函数作用域没有写return 返回值,就是表示缺少值
function foo(){}
var v1 = foo();
console.log(v1);// undefined
2) 定义函数,函数作用域有写return 返回值
注意return 有返回值的作用,也有终止代码的作用.
function add(){
return 101;// 返回101,并终止这个函数作用域的代码
return 102;//不执行
return 103;//不执行
}
var v2 = add(); // 这个v2就是add函数的返回值 v2 === add() === 101 这些就是返回值
console.log(v2); // 101
总结:
return语句只能在函数作用域中使用,不能在全局环境下使用,否则报错
return后的值就是返回值,就是函数调用后返回的结果
return 有返回值作用,也有终止代码的作用
5.函数传参
传参
1) 定义函数
在定义的时候,a和b是形参,是局部变量.只能在函数作用域中使用
function add(a,b){
var c = a + b;
return c;
}
2) 调用函数
在调用函数的时候,传递的1和2是实参, 是具体的数据
实参和形参是一一对应
var v1 = add(1,2);
console.log(v1);// 3
console.log(add(56,89));// 145
console.log(add(21,198));// 219
console.log(add());// NaN (非数字) undefined + undefined = NaN
// 示例
function sayHello(){
// 有一个对象可以获取实参数据,叫做arguments (这种集合叫做伪数组)
// console.log(arguments);
// "小明","小红","小兰","小黑"
// 0 1 2 3
var user1 = arguments[1];
console.log("hello,"+user1);
}
sayHello("小明","小红","小兰","小黑");
总结:
1. 实参和形参是一一对应的关系
2. 有形参,没有传递实参,那么形参就缺少值,是undefined
3. 有实参,没有形参,这样的代码会报错吗? 不会
4. 传递参数,让代码块重复使用更加灵活
6.匿名函数
// 1.有名称的函数(具名)
function sayHello() { }
sayHello();
// 2. 没有名称的函数(匿名)
// 需要结合标点符号使用!!!!
// 报语法错误
// 函数声明必须要有一个名称
// SyntaxError: Function statements require a function name (at
// function(){}
// 不想写函数名称,又不想报错怎么办?使用标点符号辅助
;+function () {
console.log("测试1");
}();
;-function(){
console.log("测试2");
}();
~function(){
console.log("测试3");
}();
// 常见匿名函数(这些直接调用的函数,叫做立即执行函数)
;(function(){
console.log("测试4");
})()
7.闭包
1. 闭包是什么呀?
回答: 是指封闭的执行环境。
2. 闭包具体表现 ?
回答: 一个函数(内部)有权访问另一个函数(外部)作用域的变量。
3. 作用是什么?
可以让变量私有化。
可以让变量的状态保留。
全局变量
var user = "小明1";
var user = "小明2";
var user = "小明3";
var user = "小明4";
var user = "小明5";
上述代码是几个意思?
1. 变量冲突了、污染
2. 变量重复声明了
3. 在全局环境下,全部都叫做 user 这个名称很不合理
局部变量
闭包1
function f1() {
var user = "小明1";
function foo() {
console.log("hello," + user)
}
函数也是数据,把这个函数作为f1的返回值,调用f1就可以获取foo
return foo;
}
有f1所形成的封闭环境,我们叫做闭包。
var bibao1 = f1();
bibao1();
闭包2
function f2() {
var user = "小明2";
return function () {
console.log("hello," + user);
}
}
var bibao2 = f2();
bibao2();
记住: 一个函数有权访问另一个函数作用域的变量,是闭包的表现。
闭包是指封闭的执行环境(作用域)
闭包:
一个函数(内部的)可以访问另一个函数作用域 { } 的变量,其实就是一个封闭的代码执行环 境。
优点: 1. 变量私有化,减少变量冲突
2. 闭包中变量的值状态可以被保留起来
缺点: 盲目使用闭包会出现内存泄漏的问题。
因为闭包中的变量,浏览器无法自动释放。如果闭包使用的太多太多,就会导致内存 泄漏。 (空间不足)
浏览器有一种回收机制(自带的函数)可以自动释放哪些没有利用价值的变量。
在实际开发中,能不使用闭包就尽量不使用。
如果不断创建闭包,就不断创建函数作用域(封闭环境),这些操作需要消耗内存。
8.递归
递归:是指函数自身调用(自己调用自己)。
作用:可以根据条件重复执行代码,比循环语句要灵活、强大。
递归的具体表现:1.要有终止递归的条件 2. 要有函数自身调用
这种就是函数自身调用。但是因为它没有终止代码的条件,所以执行foo代码,浏览器会卡死、死循环
function foo() {
console.log("看一眼 卡死的样子")
foo();
}
foo();
栈溢出,意思是程序中出现死循环了。
RangeError: Maximum call stack size exceeded。
1) 循环语句
for (var i = 1; i <= 5; i++) {
console.log("循环" + i + "次")
}
console.log("------------------");
2)递归函数
function loop(num) {
if (num > 5) {
终止
return;
}
console.log("执行" + num + "次");
返回、终止
return loop(num + 1);
}
loop(1);
总结:
递归是指函数的自身调用,但是使用时必须要有终止递归的条件。
可以执行重复的业务逻辑代码。
类似循环语句,但是功能比循环要灵活、强大。
------------作业练习-------------
练习一
答案:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>乘法口诀</title>
<style>
table {
/* 合并边框线 */
border-collapse: collapse;
}
table td {
border: 1px solid red;
width: 100px;
height: 40px;
text-align: center;
}
table tr:nth-child(2n) {
background-color: #ccc;
}
</style>
</head>
<body>
<!--
<table>
<tr>
<td>1 x 1 = 1</td>
</tr>
<tr>
<td>1 x 2 = 1</td>
<td>2 x 2 = 1</td>
</tr>
</table>
-->
<script>
// 要求: 制作行和列对应的乘法口诀表
// 遇到行和列这种矩阵形状,就要想到双重循环、字符串拼接
// 编码:
// 1) 定义全局变量
var html = "<table>";
// 2) 第一层:循环9次
for(var row = 1 ; row <= 9 ; row ++){
// 3) 拼接行
html += "<tr>";
// 第二层: 循环N次
for(var col = 1 ; col <= row ; col ++){
// 字符串拼接
html += "<td>"+row+"×"+col+"="+(row * col)+"</td>";
}
html += "</tr>";
}
html+="</table>";
// 循环结束,渲染字符串
document.write(html);
// console.log(html);
// 总结:
// 变量col(列)的值要小于等于变量row(行)
</script>
</body>
</html>
练习二
使用递归求下标为n的斐波那契数
问题:
斐波那契数列就是最前面两个数字分别是0,1 之后每一个斐波那契数字是之前两个数字的之和。即 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89...
要求:
1. 创建 fibonacci 函数接收 n 作为参数,n 表示需要获取的斐波那契数的下标数
2. 调用 fibonacci 函数传入下标返回斐波那契数列中指定下标的数字
3. 使用递归实现该功能
部分代码:
var fibonacci = function (n) {
代码实现
}
例如:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, .....]
0 1 2 3 4 5 6 7 8 9 10
fibonacci(4) 3
fibonacci(10) 55
编码:
console.log(fibonacci(4)) //3
console.log(fibonacci(10)); //55
// 特点:
// 1. 要有终止递归的条件
// 2. 函数自身调用
// 编码:
var fibonacci = function (n) {
// 终止递归的条件
if(n === 0 || n === 1) {
return n;
}
// 返回前面两项数字相加之和
return fibonacci(n - 2) + fibonacci(n - 1);
}
var num = fibonacci(10);
console.log(num);// 55
练习三
根据二维数组制作以下界面效果:
var arr = [ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0]]
0: 表示未选座
1:表示待出售
2:表示已出售


622

被折叠的 条评论
为什么被折叠?



