JavaScript初识
web标准:
结构: html
表现: css
行为: javascript => JS 弱类型的语言
js初识
JavaScript是一种专为与网页交互而设计的客户端脚本语言
JS组成:
ECMAScript 基础语法 ECMAScript5 => ES5 => ES6
BOM (Browser Object Model) 浏览器对象模型 操作浏览器的接口和方法 (页面跳转 前进后退 识别设备类型)
DOM (Document Object Model) 文档对象模型 提供了操作文档的接口和方法 => 获取元素 操作元素
JS的三种打印方法
1.document.write() 在文档中打印一个或多个内容(多个用逗号分隔) => 缺点:位置不好控制
document.write(123123);
document.write(“hello”);
document.write(true);
2.console.log() 在控制台打印一个或多个内容(多个用逗号分隔) => 优点:不会影响页面原本的结构(一般只是用来做 打印测试)
console.log(“hello”, “world”);
console.log(100, 200);
console.log(true, false);
3.alert() 在页面弹出一段内容 (弹出框 警告框)
alert(11111);
变量的三种声明方式
1.var a; // undefind => “undefined”
a = 10; // 10 => “number”
2.var b = 20;
3.var a = 10,b = 20;
7种数据类型
string number boolean null undefined array object
typeof方法可以判断数据类型:
console.log(typeof 1); // “number”
console.log(typeof typeof 1); // typeof “number” => “string”
字符串 遇到 “+” 会拼接
字符串 遇到 “- * / %” 会先转转数字 再计算 (a. 纯数字字符串 => 数字 b.非纯数字 => NaN)
布尔值 遇到 “+ - * / %” 会先转转数字 再计算 true => 1 false =>0
null undefined 遇到 “+ - * / %” 会先转数字 再计算 null => 0 undefined => NaN
dom操作 获取元素和绑定事件
var box = document.getElementById(“box1”) //在文档中获取对应id名的元素
强制类型转换
Number() 传入一个参数,将其转化为数字并返回 (将其他类型转化为数字)
var result = Number("100"); console.log(result); console.log(Number("100")); // 100 console.log(Number("100a")); // NaN console.log(Number(100)); // 100 console.log(Number(true)); // 1 console.log(Number(false)); // 0 console.log(Number(null)); // 0 console.log(Number(undefined)); // NaN
String() 传入一个参数,将其转化为字符串并返回 (将其他类型转化为字符串)
console.log(String("100")); // "100" console.log(String("100a")); // "100a" console.log(String(100)); // "100" console.log(String(true)); // "true" console.log(String(false)); // "false" console.log(String(null)); // "null" console.log(String(undefined)); // "undefined"
Boolean() 传入一个参数,将其转化为布尔值并返回 (将其他类型转化为布尔值)
" " 0 NaN null undefined => 转化为布尔值为false console.log(Boolean("100")); // true console.log(Boolean("100a")); // true console.log(Boolean("a")); // true console.log(Boolean(" ")); // 空格字符串 true console.log(Boolean("")); // 空字符串 false console.log(Boolean(100)); // true console.log(Boolean(-100)); // true console.log(Boolean(0.5)); // true console.log(Boolean(0)); // false console.log(Boolean(NaN)); // false console.log(Boolean(Infinity)); // true console.log(Boolean(true)); // true console.log(Boolean(false)); // false console.log(Boolean(null)); // false console.log(Boolean(undefined)); // false
parseInt() 和 parseFloat()
parseInt() parseFloat() 主要用来处理数字和字符串 ,其他类型 => NaN
parseInt() 把其他类型转化为整型(整数) 1.去单位 2.向下取整
规律: 找到第一个非数字之前的数 将其转为整数
parseFloat() 把其他类型转化为浮点的型(可以保留小数)
规律: 找到第一个非数字之前的数 保留小数
小数运算失精度的问题
官方提供的方法 num.toFixed(n) 允许所有的数字使用
num.toFixed(n) 保留n位小数 => 返回字符串
关系运算符
关系运算符 => 1. 做数值比较 => 布尔值 2. 判断是否相等 全等 => 布尔值
大于> 大于等于>= 小于< 小于等于<= == != === !==
优先级: > >= < <= 大于 == != === !==
> >= < <= 一般用于数值大小比较
= 代表赋值 等号右边的值 赋值给左边
== 相等 只比较数值,不比较类型
!= 不相等 只比较数值,不比较类型
=== 全等/恒等 既比较数值,又比较类型
!== 全等/恒等 既比较数值,又比较类型
逻辑运算符
且(&&) 或(||) 非(!)
优先级 ! 大于 && 大于 ||
赋值运算符
= += -= *= /= %=
var a = 10;
a = + 5; //自增5之后赋值给原变量 (自增5)
a = a - 5; //自减5之后赋值给原变量 (自减5)
a = a * 5; //自乘5之后赋值给原变量 (自乘5)
a = a / 5; //自除5之后赋值给原变量 (自除5)
a = a % 5; //自余5之后赋值给原变量 (自余5)
简写
a += 5; // a = a + 5;
a -= 5; // a = a - 5;
a *= 5; // a = a * 5;
a /= 5; // a = a / 5;
a %= 5; // a = a % 5;
a++ ++a的区别
a++ ++a 就结果而言 本身都自增了
如果在自增过程中出现了 其他操作
a++ 先赋值 再自增
++a 先自增 再赋值
var a = 10; var n = a++; // var n = a; a = a + 1; 先赋值 再自增 console.log(n); // 10 console.log(a); // 11 var a = 10; var n = ++a; // a = a + 1; var n = a; 先自增 再赋值 console.log(n); // 11 console.log(a);// 11
程序的三大流程控制
顺序结构 代码自上而下 按顺序执行
选择结构 根据不同的情况,执行对应代码
循环结构 重复的做一件事
选择结构
1.单分支
单分支 满足条件才 执行 否则不做任何操作
if(表达式){
执行语句;
}
2.双分支
双分支 两个选择 => 必须走一个
if(表达式){
执行语句 1;
}else{
执行语句 2;
}
求解表达式 如果表达式成立(true),则执行{}中的执行语句1 ,否则 执行else 对应的{}中的语句2
判断完毕 => 继续执行位于 选择结构之后的语句
3.多分支
if(表达式){
执行语句 1;
}else if(表达式){
执行语句 2;
}else if(表达式){
执行语句 3;
}else if(表达式){
执行语句 4;
}else{
执行语句 5;
}
关系运算符的隐式类型转换
> >= < <= == !=
1. 字符串,布尔值 在和数字比较时 会先隐式的转化为数字 再比较
2. 字符串 和 字符串 比较时, 按照顺序 比较字符的ASCII码 大小
3. null和undefined 遇到 > >= < <= 会先转数字再比较
遇到 == != 不转化 直接比较 (没有可比性)
4. null和undefined 在数值上是相等的(==)
5. NaN和任何值都不相等
++ – 的隐式类型转换
其他类型的数据(string boolean null undefined) 遇到 ++ – 会先隐式的转化为数字 再自增/自减
var a = 10; var a = "10"; // "10" => 10 a++ => 11 var a = "10a"; // "10a" => NaN a++ =>NaN var a = ""; // "" => 0 a++ => 1 var a = true; // true => 1 a++ => 2 var a = false; // false => 0 a++ => 1 var a = null; // null => 0 a++ => 1 var a = undefined; // undefined => NaN
断点使用
断点的使用流程
1. 先打断点 debugger; 哪里不会断哪里
2. 打开控制台
3. 找到source (源码)
4. 让代码重新执行一遍
a. 如果代码是页面加载时执行的 => 刷新页面
b. 如果代码在点击事件中 => 点击执行触发断点
F9/F10 下一步
F8 从当前断点直接跳到下一个断点,没有断点就跳到结尾
选择结构之switch
switch 典型的多分支
switch(week){
case 常量1: 执行语句1; break;
case 常量2: 执行语句2; break;
case 常量3: 执行语句3; break;
case 常量4: 执行语句4; break;
case 常量5: 执行语句5; break;
default:
执行语句5;
break;
}
switch中的表达式一般是一个变量/常量, 针对该变量可能出现的情况 进行列举;
switch如何执行?
switch中的表达式 和 case中的常量 依次进行 全等(===) 比较 ,如果全等则执行对应的语句, 语句执行完毕 遇到break 会跳出switch结构; 如果不全等,继续向下比较, 全都不满足则执行default之后的语句
区别:
switch 更适合做数值判断 列举变量可能出现的情况
if 更适合做范围判断, 多条件
三目运算符
三目运算符 三元条件运算符 => 本质就是一个 简单的双分支判断
var min = null;
if(a > b){
min = b;
}else{
min = a;
}
console.log(a,b,min);
简化 if … else if … else 执行语句只有一条 可以省略 {}
var min = null;
if(a > b)
min = b;
else
min = a;
console.log(a,b,min);
可以使用三目运算符
语法:
表达式1 ? 表达式2 : 表达式3;
首先求解表达式1 如果表达式1成立,则求解表达式2 否则求解表达式3
简单的双分支判断
var min = null;
a > b ? min = b : min = a;
console.log(a,b,min);
简单的判断赋值
var min = a > b ? b : a;
console.log(a,b,min);
循环初识
循环 => 周而复始,循环往复
循 => 沿着 环 => 圆
简单的来说: 重复的做一件事情 (重复的有规律的事情)
编程中遇到的循环
在满足特定条件的情况下 重复的执行某个代码段 直到条件不满足为止
循环的三要素:
(1) 初始值 循环开始的位置
(2) 循环条件 在满足特定条件的情况下,循环
(3) 自增/自减 计数 循环到了哪里
1 … 10 i<=10 i++
10 … 1 i>=1 i–
循环:
while循环
do…while循环
for循环
while语法结构
while (表达式) {
执行语句;
}
首先求解表达式 ,如果表达式成立(满足条件),则执行{}中循环语句; 语句执行完毕,再次求解表达式,如果依旧成立,则继续循环,否则会跳出循环 执行循环之后的语句
do…while语法结构
do{
执行语句;
}while(表达式);
总结:
while 先判断 再执行 => 理智型
do…while 无论条件成立与否 先执行一次 再判断 => 冲动型
对比while 和 do…while
一般情况下 更倾向于使用 while
只有在 while处理循环逻辑 比较别扭的时候使用do…while
for 语法结构
for(var i = 1; i <= 10; ){
document.write("*");
i++;
}
循环中的关键词
continue 跳过本次进入下一次 (只能在循环语句中使用,使本次循环结束,即跳过循环体中下面尚未执行的语句,接着进行下次)
注意:
(1) 位于continute之后的语句不执行
(2) 对于 while 和 do-while 循环,continue 语句执行之后的动作是条件判断(求解表达式);对于 for 循环,随后的动作是变量更新(自增/自减)。
break 循环的关键词
break用在循环中表示跳出当前循环
注意:
(1) 位于break之后的循环语句不执行
(2) 如果有多层循环嵌套,break只跳一层(当前循环)
函数初识
函数 / 方法 => 完成特定功能的工具
系统内置函数 => 官方提供的 直接用
document.write()
console.log()
alert()
String() Number() Boolean() parseInt() parseFloat()
Math.random() Math.ceil()
官方给定的函数并不能满足所有人的需求? 官方允许用户自己按照需求封装
用户自定义函数
用户自定义函数
函数的概念
函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
btn.onclick = function(){}
语法结构:
function 函数名(){
执行语句; //可以没有 也可以有很多;
return 返回值; // 指定函数执行的结果 可以有用户自行决定 , 不设置就返回undefined(默认)
// String(100) => “100”
}
函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
函数封装的流程
(1) 先将完成特定功能的代码写出来
(2) 把完成特定功能的代码 放到函数中 起一个名字
(3) 确定函数的返回值 => 返回值由用户自行决定,不设置 默认就是undefined
(4) 调用函数 => 函数名()
关于函数的调用
(1) 函数在没有调用之前,都是以文本的形参存储在浏览器的内存当中 (函数名可以理解为变量名),调用时才会执行
(2) 每次调用函数 都会执行函数中的上下文
(3) 函数遇到return就结束了 后续的代码不在执行
关于形式参数和实际参数
形式参数: 函数在封装过程中的假设性参数(可以理解为变量) 用于接收函数在调用过程中传入的实际参数
实际参数: 函数在执行过程中实际传入的值
形式参数和实际参数一一对应
局部变量
1. 在函数内通过关键词var let const声明的变量
2. 形式参数也是局部变量
作用域: 代码生效的区域
局部变量只在函数内生效 => 局部作用域(函数作用域)
全局变量
1. 在函数外 通过关键词 var let const 声明的变量
2. 不通过关键词 直接声明的变量 也是全局变量 (不规范 => 有缺陷)
全局作用域 自当前script标签开始的 任意位置均可以使用
全局作用域 包裹 局部作用域
自己有先找自己的,自己没有就向外跳一层
1. 函数内也可以访问函数外的全局变量 (自己没有就向外跳一层 ) var a = 10; // 全局 20 debugger; function fn(){ debugger; a = 20; // 全局 console.log(a); // 20 } fn(); console.log(a); // 20 2. 局部变量不会影响全局变量 (自己有先找自己的) var a = 10; // 全局 debugger; function fn(){ debugger; var a = 20; // 局部 console.log(a); // 20 } fn(); console.log(a); // 10 3. 形式参数也是局部变量 var a = 10; // 全局 function fn(a){ // 形式参数 => 局部变量 // debugger; console.log(a); // 10 a = 20; // 局部 console.log(a); // 20 } fn(a); // fn(10) console.log(a); // 10
函数的嵌套
在一个函数中 可以 嵌套调用 另外一个或多个函数
函数中 可以 嵌套声明调用 另一个函数 => 函数中声明的函数也是局部的
注意:
函数嵌套调用时 => 只有当内层函数执行完毕,外层函数才会继续向后执行 (代码执行流程)
如果向将内层函数的返回值 返回出外层函数 => 外层函数也要return该值 (关于返回值)
函数的递归
递归
函数在执行过程中 调用了自己;
注意: 递归一定要有跳出条件
死递归 => 类似死循环
function fn(){
console.log(“这是fn函数”);
fn();
}
fn();
有点类似死循环
JS预编译
var a,b; 把变量声明 提升到当前script的最前面
function fn() {
console.log(“函数调用11111111111”);
}
JS中的代码从加载到执行经历了哪些流程? 1. 语法解析 发生在代码执行之前 排查当前script中是否有语法错误 => 有错误就报错,代码不执行 2. 预编译 => 发生在代码执行之前,代码执行之前的准备工作 (1) 全局作用域 => 全局作用域中代码执行之前的准备工作 a. 变量提升 把变量声明 提升到当前script的最前面 (注意:不通过关键词声明的变量 => 全局变量 没有变量提升) b. 确定函数体 把命名函数整个函数声明 提升到当前script的最前面 (2) 函数作用域 函数中代码执行之前的准备工作 a. 变量提升 把变量声明 提升到当前函数作用域的最前面 b. 确定函数体 把命名函数函数 提升到当前函数作用域的最前面 c. 把实际参数赋值给形式参数 3. 解释执行 代码从上向下依次执行
函数的创建方式
1.命名函数 (声明式)
function 函数名(参数){表达式}
默认情况下 js语法在解析函数时 是以命名函数方式解读的 => 不能直接创建匿名函数 放在作用域中 (匿名函数一般情况下 不能单独存在)
2.匿名函数
把匿名函数存储到 变量 数组 对象 (赋值式)
1. 把匿名函数存储到 变量 数组 对象 (赋值式) var fn = function(a,b){ return a + b; } console.log(fn); var result = fn(1,2) console.log(result); var arr = [1,2,3,function(){}] var obj = { name:"张三", age:18, say:function(){ console.log("hello"); } } 2.匿名函数的自调用/自执行 (function(a,b){ return a + b; }) ;+function(a,b){ return a + b; } ;-function(a,b){ return a + b; } ;!function(a,b){ return a + b; }
3.构造函数创建 (官方给定的创建函数的方法 也属于匿名函数) => 了解(不常用)
var fn = new Function(“a”,“b”,“return a + b”);