前言

  1. js 是什么
    js 是门语言,我们用来跟浏览器沟通的一门语言,学会了这门语言我们就能和浏览器沟通了,就好像我们学会了英语,我们就能和美国人沟通一样。
  2. js 用来干什么, js 在可以在哪里运行
    1. js 可以用来跟浏览器沟通,它的具体工作一般就是:存储数据,传输数据,展示数据
    2. js 主要运行在浏览器和其它支持它的平台上

第一节 js 的引入和输出

  1. js 引入方式 demo1.html
    1. 内嵌式
    2. 外部引入式
  2. 输出语句
    1. 什么是语句
      • js语句用来向浏览器发送命令
      • 以分号作为语句结束的记号。
      • 一行代码可以有很多条语句
      • 为了压缩大小,加载更快,部署上线的时候会把代码压缩成一行。
    2. 输出到浏览器
      • document.write
      • alert
      • innerHtml
      • innerText
    3. 输出到控制台.
      • console.log()
      • console.warn()
      • console.error()
  3. 注释
    1. 注释的作用:对代码进行说明
  4. 单行注释: // 或者 /**/
    1. 多行注释:
  1. /**
  2. *
  3. *
  4. */

一、变量

  1. 变量是什么,有什么用
    • 变量是存储数据值的容器
  2. 声明(定义)变量
  3. 赋值, 再次赋值会覆盖原值

二、js 变量命名规范

  1. 区分大小写(html 不区分大小写)
  2. 标识符(比如变量名称等) (1) 以字母、下划线、合并 - 图1%20%E5%85%B6%E4%BB%96%E5%AD%97%E7%AC%A6%E5%8F%AF%E4%BB%A5%E6%98%AF%E5%AD%97%E6%AF%8D%E3%80%81%E4%B8%8B%E5%88%92%E7%BA%BF%E3%80%81#card=math&code=%E5%BC%80%E5%A4%B4%20%282%29%20%E5%85%B6%E4%BB%96%E5%AD%97%E7%AC%A6%E5%8F%AF%E4%BB%A5%E6%98%AF%E5%AD%97%E6%AF%8D%E3%80%81%E4%B8%8B%E5%88%92%E7%BA%BF%E3%80%81&id=hS6bj)或数字 (3) 驼峰式:小写字母开头,第二个打次首字母大写
  3. 注释 单行注释 多行注释
  4. 关键字和保留字 关键字:系统在使用 保留字:系统将来可能用到 _ 不能作为标识符来使用 * 用来作标识符就会报错

三、变量有哪些类型

  1. 数字 Number 类型
    • 整数
    • 小数
    • 最大值和最小值 (了解)
    • NAN : 不是数字的数字
    • typeof 判断变量的类型
  2. String 类型 字符串
    • 有三种表达方式: 双引号, 单引号, 反引号
    • 推荐使用单引号
    • 如果字符串中含有引号, 单双引号同时使用
    • 字符串可以通过 + 进行拼接
  3. Boolean 类型 true 和 false
    • 只有true和false两个值
    • 变量命名一般用疑问句
  4. Undifined 类型 undefined
    用来表示声明了变量但未初始化(赋值)
  5. Object 类型
    1. 普通对象(无序集合)
      • 对象的属性是无序的, 那个属性在前在后都没关系
      • 读取属性的两种方式
      • 修改对象属性
    2. 数组(特殊对象,有序集合)
  6. Null 类型 null
    声明一个变量准备用来存储对象
  7. 课堂练习(见本文后面的资料)

资料 1: 课堂练习

  1. 数据类型有哪几种(提问)
    1. 数字, 字符串, 布尔, 对象, undifined, null
  2. 什么时候数据类型会是 undefined?
    1. 声明了变量, 但是没有赋值, 变量的值就是undefined
  3. 字符串有哪几种形式,一般用那种?
    1. 单引号, 双引号, 反引号(模板字符串)
  4. 常见的数字有哪些?
    1. 整数, 小数, 最大值和最小值
  5. var obj = {name: ‘王菲’, age: 40} ,用两种方式在控制台打印属性值 name 的值
    1. console.log(obj.name);
    2. console.log(obj[‘name’]);
  6. 数组练习
    (1) 打印对象里数组的长度
    a. console.log(result.list.length);
    b. var arr= result.list; console.log(arr.length);
    (2) 打印数组最后一个成员的所有属性值
    console.log(result.list[result.list.length-1]); // 不太好的做法
    // 获取数组的长度
    var len = result.list.length;
    // 获取最后一个成员
    var item = result[len-1];
    // 打印该成员的所有属性
    console.log(item.categoryId);
    console.log(item.name);
    console.log(item.iconUrl);
var result = {
  "code": 666,
  "msg": "success",
  "list": [{
    "categoryId": 145,
    "name": "时令鲜果",
    "iconUrl": "/img/fresh/other/r1.png"
  }, {
    "categoryId": 243,
    "name": "海鲜水产",
    "iconUrl": "/img/fresh/other/r2.png"
  }, {
    "categoryId": 279,
    "name": "家禽蛋",
    "iconUrl": "/img/fresh/other/r3.png"
  }, {
    "categoryId": 346,
    "name": "地方农产",
    "iconUrl": "/img/fresh/other/r4.png"
  }, {
    "categoryId": 436,
    "name": "百果园公司",
    "iconUrl": "/img/fresh/other/r5.png"
  }, {
    "categoryId": 357,
    "name": "农品茗茶",
    "iconUrl": "/img/fresh/other/r6.png"
  }, {
    "categoryId": 6,
    "name": "五谷杂粮",
    "iconUrl": "/img/fresh/other/r7.png"
  }, {
    "categoryId": 311,
    "name": "牛羊肉",
    "iconUrl": "/img/fresh/other/r8.png"
  }]
}

资料 2: 作业

作业1:

把老师上课的代码全部自己敲一遍到三遍, 把有疑问的地方记录下来

作业2:

作业要求: 把答案写在语雀上, 提交作业发语雀链接即可

  1. 变量是什么,有什么用?
  2. 变量有哪几种数据类型,其中简单(基本)数据类型有哪些,复杂(引用)数据类型又有哪些?
  3. undefined 和 null 有什么区别?
  4. 根据链接里迪丽热巴的个人信息, 使用一个对象来存放她的个人信息, 迪丽热巴个人介绍
  5. 定义一个对象存放电影详情页面的数据
  6. 定义个数组存放电影列表数据信息(至少 5 条信息)
  7. 定义一个对象, 存放特惠页面信息
  8. 附加题: 有一个数组, var starList = [‘赵丽颖’, ‘迪丽热巴’, ‘佟丽娅’, ‘王丽坤’, ‘李丽珍’, ‘邓丽君’];;把数组成员输出到页面上.

附加作业:

  1. 完成卖座网电影详情静态页面的编写
  2. 完成水果生鲜销售这个网站静态页面的编写
  3. 使用今天所学的知识去描述水果生鲜每个页面的信息

问题:

有一篮苹果,两个两个的拿剩一个,三个三个的拿剩一个,四个四个的拿剩一个,五个五个的拿剩一个,六个六个的拿剩一个,七个七个的拿,能拿完,请问这篮子里有多少个苹果?

(一) if else 语句 demo1

// 条件为true, 执行if后面的括号代码, 否则执行 else 后面括号代码
if(条件) {
    // todo
}else{
    // todo
}

// 多重判断
if(){

} else if() {

} else {

}

(二) 类型转换

  1. 隐式转换 demo2-1
    运算的过程中, 类型自动进行转换, 称之为隐式类型转换
  2. 显式转换-其他类型转布尔类型 demo2-2
    • 转换方法 Boolean(变量名) 和 !!变量名
    • 转换结果为 true 或者 false
    • 字符串转布尔
    • 数字转布尔
    • undefined 转布尔
    • null 转布尔
    • 对象转布尔
总结:
- 转换方法 Boolean(变量)或者 !!变量
- 意思上若包含'无','空'的时候转为false,其他为true
- 对象全部为true
  1. 显式转换-其他类型转数字类型 demo2-3
- 转换方法 Number(变量);
- 转换结果: 数字, 0, NaN
- 字符串转数字
- 布尔转数字
- undefined 转数字
- null 转数字
- 对象转数字

总结: 
(1)数字的转换结果有三种: 数字, 0 , NaN
(2)其他类型转数字类型的时候, 就拿这三种结果区推断, 会是那一个
  1. 显式转换-其他数据类型转字符串类型 demo2-4
(1)有三种方式
  var num = 20;
  - num + ''; // 常用
  - String(num);
  - num.toString();
(2)转换规则: 把变量直接添加双引号,变成字符串

(三) 算术运算

  1. 加减乘除 + - * / % demo3-1
  2. 两个变量相加规则
(1)两个数字相加,直接相加
(2)有一个加数是字符串时,其它变量都转换成字符串,然后进行拼接 demo3-2.1
(3)NaN,null,undefined + 数字
(4)两个小数相加,有可能出现很多小数 demo3-2.2
  1. 两个小数相减规则

(四) 关系运算符(比较运算符)

  1. == 等于
  2. === 恒等于,全等于
  3. == 和 === 的区别
    • == 不同类型的变量进行比较, 不比较变量类型, 类型转换后, 只比较值, 值相等, 则为true, 否则为false
    • === 先比较类型, 若类型不同,结果为false, 若类型相同,再比较值, 值相同, 则为true
  4. 建议尽量使用 ===

(五) 逻辑运算符

  1. 逻辑非!, 取反即可
  2. 逻辑与&&: 中文里并且的意思
(1)对于布尔类型: 两者为true,结果为true demo5-2.1
(2)对于其他类型: 前者为true取后者,前者为false取前者 demo5-2.2
(3)逻辑与的妙用: 
var obj = null;
console.log(obj.a); // 报错
console.log(obj && obj.a); // 防止报错
  1. 逻辑或|| : 中文里的或者的意思 demo5-2.3
(1)对于布尔类型: 一个为true,结果为true
(2)对于其他类型:前者为true取前者, 前者为false取后者
  1. 总结: 逻辑与&& 和 逻辑或 ||, 只需要记住两句话
逻辑与: 前者为true取后者,前者为false取前者
逻辑或: 前者为true取前者, 前者为false取后者

资料1: 逻辑运算符练习

1. var num1 = 0;
   !num1;  // true
2. var num2 = 100;
   !num2;  // false
   !!num2; // true
3. var num3 = NaN;
   !num3;  // true
4. var str1 = '';
   !str1;  // true
5. var str2 = 'abc';
   !str2;  // false


10. 0 && 100;  // 0
11. 0 && NaN;  // 0
12. 100 && 0; // 0
13. 100 && NaN; // NaN
14. NaN && 0; // NaN
15. NaN && 100; // NaN

16. '' && 'abc';  // ''
17. 'abc' && '';  // ''
18. 'abc' && '456'; // '456'

19. true && true;  // true
20. true && false; // false
21. false && true; // false
22. false && false; // false

23. 0 && undefined; // 0
24. NaN && null; // NaN
25. 100 && 'abc'; 'abc'

资料2: 逻辑运算符练习2

6. var boo1 = true;
   !boo1;  // false
7. var boo2 = false;
   !boo2; // true
8. var name;
   !name; // true
9. var cat = null;
   !cat; // true

var obj;
27. 'abc' && obj.name;  // 报错
28. undefined && obj.name;  // undefined
29. obj && obj.name; // undefined

30. 0 || 100;  // 100
31. 0 || NaN; // NaN
32. 100 || 0; // 100
33. 100 || NaN; // 100
34. NaN || 0; // 0
35. NaN || 100;  // 100

36. '' || 'abc';  // 'abc'
37. 'abc' || '';  // 'abc'
38. 'abc' || '456'; // 'abc'

39. true || true; // true
40. true || false; // true
41. false || true; // true
42. false || false; // false

43. 0 || undefined; // undefined
44. NaN || null;  // null
45. 100 || 'abc';  // 100
46. 'abc' || undefined // 'abc'

47. var obj;   'abc' || obj.name;  // 'abc'
48. undefined || obj.name;  // 报错

资料3: 编程题练习

编程题, 运算并打印结果
   有一篮苹果,两个两个的拿剩一个,三个三个的拿剩一个,四个四个的拿剩一个,五个五个的拿剩一个,六个六个的拿剩一个,七个七个的拿,能拿完,请问这篮子里有多少个苹果?

资料4: 作业

  1. 编程题:
有以下两个变量 num1 和 num2,若两个变量相加等于 15.3,则输出'运算正确',否则输出'运算错误'
var num1 = 7.1;
var num2 = 8.2;

var sum = (num1*10+num2*10)/10;
if (sum === 15.3) {
    console.log('运算正确');
} else {
    console.log('运算错误');
}
  1. 编程题, 运算并打印结果
    有一篮苹果,两个两个的拿剩一个,三个三个的拿剩一个,四个四个的拿剩一个,五个五个的拿剩一个,六个六个的拿剩一个,七个七个的拿,能拿完,请问这篮子里有多少个苹果?
  2. 写出下面式子的值
typeof 100          //number
typeof true        //boolean
typeof(undefined)  //undefined
typeof({})         //object
typeof( [1,2] )   //object
typeof(NaN)       //number
typeof(null)     //object
  1. 编程题: 多重判断
    作业要求: 在屏幕输入一个数字,确定后弹出相应的年龄段
年龄划分:
“0-6岁为婴幼儿;
7-12岁为少儿;
13-17岁为青少年;
18-45岁为青壮年;
46-69岁为中年;
69岁以上为老年

<script>
    var age = prompt();
    // 先转成数字
    age = Number(age);
    // age的值是NaN,结果为true, 否则为false
    if (isNaN(age)) {
        alert('请输入数字');
    } else {
        if (age < 0) {
            alert('请输入大于或等于0的数字');
        } else {
            //  进行年龄分段的判断
            if (age < 6) {
                alert('这是个婴儿');
            } else if (age < 12) {
                alert('这是个少儿');
            }else if (age < 17) {
                alert('这是个青少年');
            }else if (age < 45) {
                alert('这是个青壮年');
            }else if (age < 69) {
                alert('这是个中年人');
            }else {
                alert('这是个老年人');
            }
        }
    }
</script>
  1. 写出下面式子的值

'1.23' == 1.23 
0 == false 
null == undefined 
NaN == NaN 
1 == '1'       
1 === '1'       
1 + '2' === '1' + 2  
1 + true === false + 2 
1 + null == undefined + 1 
'a' - 'b' == 'b' - 'a' false
4 == '4.00' 
4 === '4.00' 
0 == false  
0 == null 
null == false 


加减作业题
var score = 50;
var grade = '7';
score + 10;     
score + '10';    
score + null;     
score + undefined; 
score + NaN;              
score + 10;
score + '10';
score + null;
var num1 = 8;       
var num2 = '8';
num1 - num2;              
num1 - 'web01';             
num1 - null;              
num1 - undefined;          
num1 - true;             
num1 - false;             
num1 - num2;

前言

  1. 调试代码,找出代码中的问题经常使用 debugger 来打断点, 而要能在准确位置打上断点, 就必须熟悉程序的执行流程
  2. 流程控制语句有三种: 顺序结构, 分支结构和循环结构

(一) 顺序结构(默认)

  1. 程序默认从上到下一句一句代码执行, 这就是顺序结构
  2. 打断点操作

(二) 分支结构

  1. if else
  2. 三目运算符
  3. switch break

(三) 循环结构

1. for 循环

  1. 标准 for 循环四要素
for(var i=0;i<5;i++){
    console.log('i=',i);
}

(1)循环变量初始值 var i=0;
(2)循环条件 var i<5;
(3)循环变量改变 i++;
(4)循环体 console.log('i=',i);
  1. for 循环的运行规律
(1)第一次循环 1->2->4->3
(2)第二次循环 2->4->3
(3)第三次循环 2->4->3
........ 当循环条件不满足,就会结束循环
  1. continue 和 break
  2. for循环的四个部分不是必须的
  3. 死循环

2. 数组遍历和对象遍历

3. while 循环 和 do while 循环

(四) 打断点调试

  1. 没有得到期待的结果的时候, 应该怎么办
    1. 打开控制台, 看看有没有报错
    2. 打断点进行调试代码
  2. 打断点
    1. 代码运行流程
      1. 从上到下,逐行执行
      2. 遇到分支语句只会执行其中的一个分支
      3. 遇到for循环, 要等到for循环结束才继续往下执行
      4. 遇到函数, 先声明函数,函数内的代码并不会离职执行, 只有函数被调用时才执行
    2. 断点的各个符号的含义
    3. 断点打得准的关键是: 清楚代码运行流程, 也就是清楚代码会往哪里”走”

前言:

完成以下练习

编写代码:计算 1-100 相加并输出结果, 计算 20-80 相加,并输出结果, 计算 100-200 相加,并输出结果

没学函数前, 我们可能会写三遍 for 循环, 有了函数之后只需要写一遍即可.

(一)函数的声明函数的调用

1.1 函数是什么

封装多行语句,可以重复使用,类型为 function

1.2 声明函数和调用函数

<script>
    // 函数声明,实现1道100累加
    function sum() { 
        var sum = 0;
        for(var i=1;i<=100;i++) {
            sum += i;
        }
        console.log(sum);
    }

    // 函数的调用: 函数名+();
    sum();
    sum();
    sum();
    sum(); 

</script>

1.3 函数和变量声明提前

  1. 函数是一等公民, 优先声明
say();  // 这样写没有错, 函数会先声明
function say() {
  console.log('hello');
}
  1. 变量是先声明后赋值
<script>
    console.log(a); // 输出undefined,因为a会先声明, 单不赋值
    var a = 100;
    console.log(a);  // 变量a在这里才赋值, 所有a的值为100;
</script>

1.4 对象中的函数(方法)

alert 就是 window 对象的一个方法

<script>
    var obj = {
        name: '张三',
        age: 100,
        say: function() {
            console.log('我是狂徒');
        }
    }

    obj.say();  // 调用对象中的方法


    alert(222);
    window.alert(3333);

</script>

补充知识: 对象和数组

(1) 基本数据类型:

  1. 数字
  2. 布尔
  3. undefined
  4. null
  5. 字符串

(2) 复杂数据类型(引用数据类型)

  1. 对象
  2. 数组
  3. function
// 数组
<script>
    // 1.声明一个数组,第一个成员的下标为0
    var list = ['a','b','c','d'];
    // 2.访问数组通过下标, 其中第一个成下标为0,其他成员依次类推
    console.log('下标为0的成员',list[0]); // 读取下标为0的成员

    // 3.数组的长度
    console.log('数组长度',list.length); // 长度为4

    // 4.读取最后一个成员的下标: 长度-1
    var len = list.length;
    var last = list[len-1];  // 长度-1
    console.log(last);

    // 5.数组遍历
    for(var i=0;i<list.length;i++) {
        console.log('第'+(i+1)+'成员',list[i]);
    }
</script>


// 对象
<script>
    // 1.声明对象,对象是无序
    var person = {
        // key(键,属性)  value(值)  => 键值对  
        username: '法外狂徒张三',
        say: function () {
            console.log('我是张三');
        },
        age: 100
    }
    // 2.获取对象属性
    console.log('username', person.username);
    console.log('username', person['username']);

    // 3.修改对象的属性
    person.username = 'zhangsan';
    console.log('新的名字', person.username);

    // 4.调用对象的方法
    person.say();
</script>

(3) 基本数据类型和引用数据类型的存储

  1. 基本数据类型存放在栈区
  2. 引用数据类型存放在堆区(它的引用存放在栈区)
  3. 以下是基本数据类型和引用数据类型的存放方式

image.png

  1. 练习: 说出下面代码运行的结果
var a = 100;
var b = a;
b = 200;
console.log(a); // a的值是: 100

var obj1 = {
    name: '张三',
  age: 100
}
var obj2 = obj1;
obj2.name = '李四';

console.log(obj1.name);  // obj1.name的值是多少 李四

(二)函数的调用方式

2.1 手动调用

2.2 绑定一个事件来调用

这里的函数叫: 监听器, 事件句柄

一个例子

从页面上输入两个加数,绑定事件,加上两个加数相加的结果,并显示在页面上

  1. 获取元素节点
document.querySelector('#inp');  //获取id为inp的标签
  1. 获取input标签的值
var $inp = document.querySelector('input'); // 获取input标签
var value = $inp.value; // 读取input标签的值
<!DOCTYPE html>
<html lang="en"> 
<body>
      <input id="num1" type="text">+<input id="num2" type="text"><br/><br/>
      <button id="btn" onclick="add();">计算</button> 
      <input type="text" id="sum">

    <script>
        // 获取标签
        var $num1 = document.querySelector('#num1');
        var $num2 = document.querySelector('#num2');
        var $sum = document.querySelector('#sum');

        function add() {
            // 获取两个加数的值
            var num1 = $num1.value;
            var num2 = $num2.value;
            var sum = num1*1+num2*1;
            $sum.value = sum;
        }
    </script>
</body>
</html>

(三)函数传递参数

3.1 实参和形参

<script>
    // num1,num2是形参, 用来接收数据,形参的名字自定义
    function add(num1,num2) {
        var sum = num1+num2;
        console.log('相加结果:',sum);
    }

    // 100,200是实参
    add(100,200);
</script>

3.2 函数参数的类型

  1. 参数是基本数据类型
  2. 参数是引用数据类型
  3. 参数是函数(难)
<script>
    // 基本数据类型传参,若形参改变了, 实参并不会跟着改变
    function add(a,b) {
        a = a*2;
        b = b*2;
        var sum = a+b;
        // console.log('sum',sum);
    }
    var n1 = 10;
    var n2 = 20;
    add(n1,n2);
    // console.log('n1',n1);
    // console.log('n2',n2);


    // 传入引用数据类型, 形参改变了, 实参也会跟着改变
    function say(obj) {
        obj.name = '李四';
        console.log(obj.name); // 李四
    }

    var person = {
        name: 'zhangsan',
        age: 100
    }
    say(person);
    console.log(person.name);  // 李四
</script>


// 回调函数,函数参数是个函数
<script>
    // 回调函数
    function  waterDispense(fn) {
        console.log(2); 
        fn('热水来了');
    }
    function getWater(str) {
        console.log(3);
        console.log(str);  
    }

    console.log(1);
    debugger;
    waterDispense(getWater);  

</script>

(四)函数返回值

4.1 使用 return 返回计算的结果
4.2 没写 return, 默认返回undefined
4.3 alert(), console.log(); 调用结束后为什么有个”undefined”出现
4.4 return 之后的代码不执行

<script>
  // 1.函数返回值,使用return把运算结果返回给调用者
    function add(a,b) {        
        var sum = a+b;
        return sum;
    }

        // result的值是函数里return后面跟着的数据
    var result = add(10,20);
    console.log('result',result);
</script>


// 不写return,默认返回undefined
function test() {

}
test(); // 返回undefined


<script>
  // return之后的代码不执行
    function add(a,b) {        
        var sum = a+b;
        return sum;
        console.log(1);
        console.log(2);
    }

    var result = add(10,20); 
</script>

(五)作用域

5.1 什么是作用域

5.2 全局作用域和全局变量

  1. 全局执行环境(全局作用域): window
  2. 全局变量: 在全局作用域下声明的变量

5.3 局部作用域和局部变量

  1. 局部执行环境(局部作用域): 函数内部就局部作用域
  2. 局部变量:
    1. 声明在函数内部的变量是局部变量
    2. 局部变量在函数执行的时候存在, 执行结束被销毁
  3. 声明对象不写var,也是全局变量(不推荐)

5.4 作用域访问规则

  1. 函数内部可以访问函数外部的变量
  2. 函数外部不可以访问函数内部的变量
  3. 作用域链
  4. 没有块级作用域
<script>
  // 规则1和规则2
    var username = '张三';
    function say() {
        var age = 100;
        console.log(username);
    }

    say();
    console.log(age);  // 会报错, 函数外部无法访问函数内部变量
</script>


// 作用域链
<script>
    // var username = '张三';
    function say() {
        // var username = '李四';
        function say2() {
            // var username = '老王'; 
            console.log(username);
        }
        say2();
    }
    say();
</script>


// 没有块级作用域
<script>
    {
        var a = 100;
    }
    console.log(a); // a不是在函数里声明, 所以它是全局变量

    for(var i=0;i<3;i++) {  
        // todo
    }
    console.log(i);  // 3 i不是在函数里声明, 所以它是全局变量
</script>

作业1:
编写代码:计算 1-100 相加并输出结果, 计算 20-80 相加,并输出结果, 计算 100-200 相加,并输出结果

作业2:
编写一个简单的计算器

  1. 自己设计界面
  2. eval可以执行代码
var str = '1+2+3';
var sum = eval(str); // 6

计算器.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css">
    <style>
        * { margin: 0; padding: 0; }
        ul,
        li {
            list-style: none;
        }
    </style>
</head>

<body>
    <div class="box">

        <div class="inp-box">
            <input id="inp" class="inp" type="text" placeholder="简单计算器">
        </div>
        <ul class="list">
            <li>C</li>
            <li>CE</li>
            <li onclick="add('%',true)">%</li>
            <li onclick="add('/',true)">/</li>
            <li onclick="add(7)">7</li>
            <li onclick="add(8)">8</li>
            <li onclick="add(9)">9</li>
            <li onclick="add('*',true)">x</li>

            <li onclick="add(4)">4</li>
            <li onclick="add(5)">5</li>
            <li onclick="add(6)">6</li>
            <li onclick="add('-',true)">-</li>
            <li onclick="add(1)">1</li>
            <li onclick="add(2)">2</li>
            <li onclick="add(3)">3</li>
            <li onclick="add('+',true)">+</li>

            <li onclick="add(0)" style="width: 210px;">0</li>
            <li onclick="add('.',true)">.</li>
            <li>=</li>
        </ul>
    </div> 

    <script src="demo.js"></script>
</body>
</html>

style.css 代码

.box {
  margin-top: 100px;
  width: 440px;
  background-color: #ebebeb;
  margin: 0 auto;
  padding: 5px;
}
.inp-box {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 5px;
}
.inp-box .inp {
  width: 100%;
  height: 45px;
  border: none;
  text-indent: 20px;
  font-size: 25px;
  outline: none;
}
.list {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}
.list li {
  user-select: none;
  width: 100px;
  height: 65px;
  text-align: center;
  line-height: 65px;
  font-size: 20px;
  background-color: #fff;
  margin-bottom: 10px;
  cursor: pointer;
}

demo.js 代码

/**
 * 第一个功能
 * 点击数字或者运算符,输入框显示
 */

// 1.1 绑定点击事件
// 1.2 数字上屏

// 获取输入框对象
var $inp = document.querySelector("#inp");
// str用来存放我们点击的数字或者运算符
var str = '';
/**
 * @param {*} num 点击的数字或者运算符
 * @param {*} flag 值为true,说明点击的是运算符
 */
function add(num,flag) { 
    // 输入框的值为空, 并且点击的运算符,就不往下执行
    if(!str && flag) {
       return false;
    }
    // if(str==='' && flag===true) {
    //    return false;
    // }

    // last表示str字符最后一个字符
    var last = str[str.length-1];
    // last转换为数字之后,值为NaN,说明last不是数字
    // 如果值不是数字, boo为true, 否则为false
    var boo = isNaN(Number(last));
    // 当前面一个字符是运算符,再点击运算符也不往下执行
    if(flag && boo ) {
        return false;
    }
    // 拼接字符串
    str += num;
  // 把str显示在输入框
  $inp.value = str;
}


// 功能2: 清零
function clearData() {
    // 将输入的值置空
    $inp.value = '';
    // 将str的值,变为空,不然的话再点击数字的时候, 会跟原来的值拼接在一起
    str = '';
}


// 功能3:计算
function compute() {
    // last表示str字符最后一个字符
    var last = str[str.length-1];
    // 判断最后一个字符是不是数字
    var boo = isNaN(Number(last));
    if(boo) {
        alert('式子不正确, 检查');
        return false;
    }

    // 使用eval计算式子的值
    var result = eval(str);
    // 把结果显示在输入框
    $inp.value = result;
    // 把str的值置空,不然前面式子会一起拼接
    str = '';
}

内置函数关键

  1. 它有什么作用
  2. 需要给它传什么参数
  3. 调用结束之后, 返回什么(有些方法没有返回)

(一) 字符串常用方法

  1. length // 字符串的长度
  2. trim() // 去掉字符串前后的空格
  3. toLowerCase() // 转小写字母
  4. toUpperCase() // 转大写字母
  5. charAt() // 返回字符的位置, 若没有,返回-1
    1. 作用: 方法可返回指定位置的字符
    2. 参数: 下标
    3. 返回: 下标对应的字符
  6. indexOf()
    1. 作用: 返回检测字符串的位置
    2. 参数: 字符或者字符串
    3. 返回: 字符串的位置
  7. lastIndexOf() // 同上,但从后面开始检查
  8. includes()
    1. 作用: 检查字符串是否包含指定字符
    2. 参数: 字符串
    3. 返回: 若包含返回true, 否则返回false
  9. split()
    1. 作用: 字符串转数组
    2. 参数: 接收一个参数,作为转换的标志
    3. 返回: 一个数组
  10. substring()
  11. 作用: 截取字符串
  12. 参数: 第一个参数(开始位置),第二参数(结束位置)
  13. 返回值: 截取后端字符串, 包含开始位置, 不包含结束位置
  14. slice()
  15. 作用: 截取字符串, 用法类似substring, 但可以负数
  16. substr()
  17. 作用: 截取字符串,
  18. 参数: 第一个参数是开始位置, 第二个参数是截取的字符个数
  19. 返回值: 截取后的字符串
  20. match()
  21. 作用: 检查字符串是否包含某个指定字符串
  22. 参数: 一般是字符串或者正则
  23. 返回值: 若包含, 返回一个数组, 不包含返回null
  24. replace()
  25. 作用: 替换
  26. 参数: 字符串或正则
  27. 返回值: 替换后的字符串
  28. replaceAll()
  29. 作用: 全部替换
  30. 参数: 字符串
  31. 返回值: 替换后的字符串
<script>
    // 1.长度
    var str = 'abcd';
    console.log('长度',str.length);

    // 2.trim()
    var str2 = ' abcd ';
    var newStr2 = str2.trim();
    console.log('newStr2',newStr2);  // 

    // 3.toLowerCase
    var str3 = 'asdfa2ASDFSAasdf';
    var newStr3 = str3.toLowerCase();
    console.log('newStr3',newStr3)

    // 4.toUpperCase
    var str4 = 'asdfa2ASDFSAasdf';
    var newStr4 = str4.toUpperCase();
    console.log('newStr4',newStr4)

    // 5.charAt()
    var str5 = 'abcde';
    var letter5 = str5.charAt(2);
    console.log('letter5',letter5);

    // 6.indexOf();
    var str6 = 'abczdzhangsanabc';
    var index6_1 = str6.indexOf('z');
    var index6_2 = str6.indexOf('zhangsan');
    console.log('index6_1',index6_1); // 3
    console.log('index6_2',index6_2); // 5

    // 7.lastIndexOf
    var str7 = 'abczdzhangsanabc';
    var index7_1 = str7.indexOf('c');  // 2
    var index7_2 = str7.lastIndexOf('c'); // 15

    // 8.includes()
    var str8 = '我是中国人';
    var boo8 = str8.includes('我');  // true
    var boo8_2 = str8.includes('们'); // false

    // 9.split();
    var str9 = '张三,李四,王五,陈六';
    var list9 = str9.split(',');  
    console.log('list9',list9);   // ['张三','李四','王五']

    // 10. substring()
    var str10 = 'abcdefg';
    var newStr10 = str10.substring(1,4); // 参数可以是负数, 但是不一般不用负数
    console.log('newStr10',newStr10);  // 

    // 11. slice()
    var str11 = 'abcdefg';
    var newStr11 = str11.slice(1,-2); // 参数可以是负数,-1表示最后一个字符 
    console.log('newStr11',newStr11);  // 

    // 12. substr()
    var str12 = 'abcdefg';
    var newStr12 = str12.substr(1,3); // 第二个参数表示截取的字符个数
    console.log('newStr12',newStr12);  // 

    // 13. match();
    var str13 = '我是中国人';
    var res13_1 = str13.match('们');  // 
    var res13_2 = str13.match('中'); // 

    // 14.replace()
    var str14 = '我是中国人,我是广西人';
    var newStr14_1 = str14.replace('我','他'); // 
    var newStr14_2 = str14.replaceAll('我','他'); //
    console.log('newStr14_1',newStr14_1); 
    console.log('newStr14_2',newStr14_2); 
</script>

(二) 常用的数组方法

  1. pop() 会改变原来数组
    1. 作用: 删除数组的最后一个元素
    2. 参数: 无
    3. 返回值: 被删除的元素。
  2. push() 会改变原来数组
    1. 作用: 向数组的末尾添加一个或更多元素
    2. 参数: 新增成员
  3. shift() 会改变原来数组
    1. 作用: 删除数组的第一个元素
    2. 参数: 无
    3. 返回值: 被删除的元素。
  4. unshift() 会改变原来数组
    1. 作用: 向数组的开头添加一个或更多元素
    2. 参数: 新增成员
  5. map() 不会改变原来数组
    1. 作用: 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
    2. 参数: 一个函数 funciton(currentValue ,index ,arr )
      1. currentValue 当前成员的值
      2. index 当前元素的索引值(当前成员的下标)
      3. arr 当前元素属于的数组对象
    3. 返回值: 返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值
  6. filter() 不会改变原来数组
    1. 作用: 筛选数组, 找出符合条件的成员
    2. 参数: 一个函数
    3. 返回值: 一个新的数组
  7. forEach()
    1. 作用: 遍历数组
    2. 参数: function(item,index) {}
    3. 返回值: undefined
  8. isArray() 判断对象是否为数组。
  9. find()
    1. 作用: 在数组查找符合条件的成员
    2. 参数: 函数
    3. 返回值: 符合条件的第一个成员, 若没有会返回?
  10. findIndex()
  11. 作用: 在数组查找符合条件的成员的下标
  12. 参数: 函数
  13. 返回值: 符合条件的第一个成员的下标, 若没有会返回?
  14. indexOf() 搜索数组中的元素,并返回它所在的位置。若元素不在数组里, 会返回?
  15. lastIndexOf() 搜索数组中的元素,并返回它最后出现的位置。若元素不在数组里, 会返回?
  16. some()
  17. 作用: 检测数组元素中是否有元素符合指定条件。
  18. 参: function() {}
  19. 返回值: true或false
  20. includes() 判断一个数组是否包含一个指定的值。 // 成员只能是基本数据类型
  21. join()
  22. 作用: 把数组变成字符串
  23. 参数: 连接符(一个字符)
  24. 返回值: 一个字符串
  25. slice() 选取数组的一部分,并返回一个新数组。
  26. splice() 会修改原来的数组
  27. 作用:
    1. 删除数组中某个成员
    2. 替换某个成员
  28. 参数:
    1. index成员的下标
    2. count删除的个数
    3. newItem新的成员
  29. 返回值: 作用不大,不用理会
  30. sort() 对数组的元素进行排序。
  31. reverse() 反转数组的元素顺序。
<script>
    // 1.pop()
    var list1 = [1,2,3];
    list1.pop();
    console.log('list1',list1); // 

    // 2. push();
    var list2 = [1,2,3];
    list2.push(4);
    console.log('list2',list2); // 

    // 3. shift();
    var list3 = [1,2,3];
    list3.shift();
    console.log('list3',list3); // 

    // 4. unshift();
    var list4 = [1,2,3];
    list4.unshift(0);
    console.log('list4',list4); // 

    // 5.map(); 改头换面
    var list5 = [
        {name: 'zhangsan'},
        {name: 'lisi'},
        {name: 'wangwu'}
    ]

    var newList5 = list5.map(function(item){
        var name = item.name.toUpperCase();
        return {
            username: name,
            age: 100
        }; 
    });
    console.log('newList5',newList5);

    // 6.filter()
    var list6 = [ { name: 'lurui', age: 20, gender: '男' }, { name: 'linwei', age: 19, gender: '男' }, { name: 'wangyuxia', age: 18, gender: '女' } ]

    // 把性别是男的成员筛选出来    
    var newList6_1 = list6.filter(function(item,index){
        return item.gender === '男';
    });
    console.log('newList6_1',newList6_1);  // 

    // 找出年龄大于18的成员
    var newList6_2 = list6.filter(function(item){
        return item.age > 18;
    })
    console.log('newList6_2',newList6_2);  // 


    // 7. forEach()
    var list7 = [ { name: 'lurui', age: 20, gender: '男' }, { name: 'linwei', age: 19, gender: '男' }, { name: 'wangyuxia', age: 18, gender: '女' } ]
    list7.forEach(function(item,index) {
        console.log(index,item);
    }) 

    // 8. isArray
    var list8 = [1,2,3];
    var boo8 = Array.isArray(list8);
    var boo8_2 = Array.isArray(10);
    console.log('boo8',boo8);  // 
    console.log('boo8_2',boo8_2);  // 

    // 9.find()
    var list9 = [ { name: 'lurui', age: 20, gender: '男' }, { name: 'linwei', age: 19, gender: '男' }, { name: 'wangyuxia', age: 18, gender: '女' } ]
    var obj9 = list9.find(function(item) {
        return item.gender === '男';
    })
    console.log('obj9',obj9);  // {name: "lurui", age: 20, gender: "男"}
    var obj9_2 = list9.find(function(item) {
        return item.gender === '未知';
    })
    console.log('obj9_2',obj9_2);  // undefined

    // 10.findIndex()
    var list10 = [ { name: 'lurui', age: 20, gender: '男' }, { name: 'linwei', age: 19, gender: '男' }, { name: 'wangyuxia', age: 18, gender: '女' } ]
    var obj10 = list10.findIndex(function(item) {
        return item.gender === '男';
    })
    console.log('obj10',obj10);  // 0
    var obj10_2 = list10.findIndex(function(item) {
        return item.gender === '未知';
    })
    console.log('obj10_2',obj10_2);  // -1

    // 13.some(); 
    var list13 = ['a','b','a','c'];
    var boo13 = list13.some(function(item){
        return item === 'a';
    })
    var boo13_2 = list13.some(function(item){
        return item === 'd';
    })
    console.log('boo13',boo13);  // true
    console.log('boo13_2',boo13_2); // false

    // 15. join()
    var list15 = ['a','b','a','c'];
    var str15_1 = list15.join(); 
    var str15_2 = list15.join('-');
    var str15_3 = list15.join('/');
    console.log('str15_1',str15_1); // 
    console.log('str15_2',str15_2); // 
    console.log('str15_3',str15_3); // 

    // 16.slice()
    var list16 = ['a','b','a','c'];
    var newList16 = list16.slice(1,3);
    console.log('newList16',newList16);


    // 17.splice()
    var list17 = ['a','b','c','d','e'];
    list17.splice(1,1);
    console.log('list17',list17);

    var list17_2 = ['a','b','c','d','e'];
    list17_2.splice(1,1,'hhh');
    console.log('list17_2',list17_2);

     // 18.sort(); 字母排序
     var list18 = ['a','e','c','b'];
     list18.sort(); 
     console.log('list18',list18);  // 调用sort(), 字母按升序排列


     // 数字排序
     var list18_2 =['a','e','c','b'];  // 对于数字排序,需要传入一个函数
     list18_2.sort(function(a,b) {
        return b-a;  // a-b升序,b-a降序
     });
     console.log('list18_2',list18_2);

     // 成员对象
     var list18_3 = [ { name: 'lurui', age: 20, gender: '男' }, { name: 'linwei', age: 19, gender: '男' }, { name: 'wangyuxia', age: 18, gender: '女' } ]
     list18_3.sort(function(a,b) {
        if (a.age<b.age) {
            return 1;
        } else if (a.age>b.age) {
            return -1;
        } else {
            return 0;
        }
     })


    // 19.reverse()
    var list19 = ['a','b','c'];
    var newList19 = list19.reverse();
    console.log('newList19', 'newList19');






</script>

(三) 日期对象常用方法和插件

3.1 创建日期对象的几种方式
    // 方式1: 没有参数
    var date = new Date();
    console.log('当下时间:',date); 

    // 方式2: 参数是日期字符串 2021-09-07
    var date2 = new Date('2021-09-07');
    console.log('昨天',date2);

    // 方式3: 参数是毫秒数
    var date4 = new Date(1631090920638);
    console.log('data4',date4);

    var date5 = new Date(0);
    console.log('日期的起点',date5);

    // 返回1970到现在的毫秒数
    var time = Date.now();
    console.log('毫秒数',time);

3.2 日期对象的常用方法
  1. 获取年月日时分秒 (月份+1)
  2. 获取星期
  3. 获取毫秒数
  4. 日期比较
  5. moment.js 日期函数库
    http://momentjs.cn/
  6. 一个cdn网站: https://www.bootcdn.cn/
<script>
  // 1.获取年月日时分秒 (月份+1)
    var date = new Date();
    console.log('date',date);
    var Y = date.getFullYear(); // 年
    var M = date.getMonth()+1;  // 月
    var D = date.getDate();  // 日
    var h = date.getHours();  // 时
    var m = date.getMinutes(); // 分
    var s = date.getSeconds(); // 秒

    // 月和日小于10,在它的前面+'0'
    M = M<10?'0'+M:M;
    D = D<10?'0'+D:D;

    var str = Y+'/'+M+'/'+D + ' '+h+':'+m+':'+s;
    console.log(str); 

    // 2.获取星期
    var week = date.getDay(); // 3
    // 3.获取毫秒数
    var time = date.getTime();
    // 4.日期比较
    var date1 = new Date();
    var date2 = new Date();
    // date2与date1的时间间隔
    var time = date2-date1;
</script>
// moment.js 一个日期的js库
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://cdn.staticfile.org/moment.js/2.24.0/moment.min.js"></script>
</head>
<body>


    <script>
        var date = moment().format('YYYY-MM-DD, hh:mm:ss');
        console.log(date);
    </script>
</body>
</html>

(四) Math对象

  1. Math.round(x) // 四舍五入
  2. Math.abs(x) // 求 x 的绝对值
  3. Math.floor(x) // 向下取整
  4. Math.ceil(x) // 向上取整
  5. Math.random() // 随机数
  6. sqrt(x) // 求 x 的平方根
  7. toFixed(x) 保留x位小数
  8. parseInt 把小数变整数
  9. 获取某个范围内的随机数 比如: 获取5-10之间的一个随机数
<script>
    // 1.round();
    var num1 = 123.5;
    var newNum1 = Math.round(num1);
    console.log('newNum1',newNum1);  // 124

    // 2.abs();
    var num2 = -1;
    var newNum2 = Math.abs(num2);
    console.log('newNum2',newNum2);  // 1

    // 3.floor();
    var num3 = 3.7;
    var newNum3 = Math.floor(3.7);
    console.log('newNum3',newNum3); // 3

    // 4.ceil();
    var num4 = 4.7;
    var newNum4 = Math.floor(4.7);
    console.log('newNum4',newNum4); // 5

    // 5.random() 0到1的随机数, 包含0不包含1
    var num5 = Math.random();
    console.log('num5',num5);

    // 6.sqrt();
    var num6 = 4;
    var newNmum6 = Math.sqrt(num6);
    console.log('newNmum6',newNmum6); //2

    // 7.toFixed()
    var num7 = 2.238234;
    var newNum7 = num7.toFixed(2);
    console.log('newNum7',newNum7); // 2.24 会四舍五入

    // 8.parseInt()
    var num8 = 2.234234;
    var newNum8 = parseInt(num8);
    console.log('newNum8',newNum8) 

        // 9.两个数之间的随机数
        function madeRandom(max,min) {
            return    Math.floor(Math.random()*(max-min)+min)
         }
        var num = madeRandom(20,10);

</script>

(五) 练习

  1. 城市列表过滤
  2. 饿了么下拉菜单
  3. 列表删除某个元素