初识 JavaScript
参照传智播客的视频。
定义
javascript是一种运行在客户端的脚本语言 (与css类似)
作用
- 表单动态检验
- 网页特效
- 服务端开发(Node.js)
- 桌面程序(Electron)
- APP(Cordova)
- 控制硬件-物联网(Ruff)
- 游戏开发(cocos2d-js)
js的组成
1.javascript语法(ECMAScript)
2.面向文档对象模型(DOM)
3.浏览器对象模型(BOM)
JavaScript 变量
定义
程序在内存中申请的一块用来存放数据的## 空间
使用
1.声明变量 2. 赋值
// 声明用关键词var
var age; // 声明一个名称为age的变量
// 赋值
age=10; // 给age这个变量赋值
// 变量的初始化
var age = 18; // 推荐写法
案例
变量的使用: 1.弹出一个对话框,提示用户输入姓名
2.弹出一个对话框,输出用户刚才输入姓名
var myname = prompt('请输入您的姓名');
alert(myname);
输出结果:
变量语法扩展
- 更新变量
var age = 18;
age = 20; // 第二次的值会把第一次的完全覆盖
- 声明多个变量
var age=18,address='火影村'; // 多个变量之间用逗号隔开
- 特殊情况
var sex; // 只声明不赋值 结果是undefined
console.log(tel); 不声明,不赋值,直接使用某个变量会报错的
qq = 110; // 不声明直接赋值使用
变量的命名规则
案例
交换两个变量的值
var temp; // 临时变量
var apple1='青苹果';
var apple2 = '红苹果';
temp = apple1;
apple1 = apple2;
apple2 = temp;
console.log(apple1);
console.log(apple2);
小结
JavaScript数据类型
数据类型简介
// js的变量数据类型是只有程序在运行过程中,根据等号右边的值来确定的
var num = 10; // 数值型
var str = 'pink' // 字符串型
// js动态语言,变量的数据类型可以变化
简单数据类型
数字型 Number
var num = 10;
var PI = 3.14;
// 1.八进制 0-7 我们程序里面数字前面加0 表示八进制
var num1 = 010; // 010 八进制 转换为10进制 就是8
// 2.十六进制 0-9 a-f 在程序数字前加0x 表示十六进制
var num2= 0xa; // 10
// 3.数字型的最大值 (了解)
alert(Number.MAX_VALUE);
alert(Number.MIN_VALUE);
// 三个特殊词 (了解)
alert(Infinity) // 无穷大
alert(-Infinity) // 无穷小
alert(NaN) // 非数字
isNaN() 这个方法用来判断非数字
字符串型 String
可以是单引号或双引号 在js中推荐用单引号
嵌套
口诀: 外双内单,内双外单
var str = '我是一个"高富帅"的程序员';
字符串转义符
转义符 | 解释说明 |
---|---|
\ n | 换行符 newline |
\ \ | 斜杠 \ |
\ ’ | 单引号’ |
\” | 双引号" |
\t | tab缩进 |
\b | 空格 |
字符串长度
获取字符串的长度可用length属性
var str = 'my name is andy';
console.log(str.length) // 15
字符串拼接 +
拼接方式:字符串+任何类型 = 拼接之后的字符串
+号口诀:数值相加,字符相连
拼接加强: 将字符串和变量来拼接
var age =18;
console.log('pink老师'+ age +'岁') // pink老师18岁
// 口诀: 引引加加
案例
显示年龄 简单js交互
1.弹出一个输入框(prompt),让用户输入年龄
2.把输入的值用变量保存起来,把字符拼接起来
3.使用alert语句弹出警示框
布尔型 Boolean
有两个值: true 和false
var flag = true;
var flag1 = false;
console.log(flag + 1); // 2
console.log(flag1 + 1); // 1
undefined 未定义和Null 空数据
变量声明未赋值 就是undefined 数据类型
Null就是空数据类型
console.log(undefined + 'pink');// undefinedpink
console.log(undefined + 1); // NaN
console.log(null + 'pink'); // nullpink
console.log(null + 1); // 1
获取变量的数据类型
typeof属性可获取
var num = 10;
console.log(typeof num); // Number
var str = 'pink';
console.log(typeof str); // String
var flag = true;
console.log(typeof flag);// Boolean
var vari = undefined
console.log(typeof vari);// undefined
var timer = null;
console.log(typeof timer); // object
字面量
是在源代码中一个固定值的表示方法
数据类型转换
转换为字符串类型
加号拼接字符串是重点
// 隐式转换
var num = 10;
console.log(num + '');
转换为数字型(重点)
记住前两个
var age = prompt('请输入您的年龄');
// parseInt(变量) 得到结果是整数
console.log(parseInt(age));
console.log(parseInt('3.94')); // 3 取整
console.log(parseInt('120px')); // 120 会去掉px单位
console.log(parseInt('rem120px')); // NaN
// parseFloat(变量) 得到结果是小数 浮点数
案例
1.计算年龄
2.简单加法器
转换为布尔型
代表空、否定的值会被转换为false,如 ’ '、0、NaN、null、undefined
其余值全部是true
作业案例
var uname = prompt('请输入您的姓名');
var age = prompt('请输入您的年龄');
var sex = prompt('请输入您的性别');
var ages = prompt('您现在多少岁了');
var page = parseInt(ages) + 5;
console.log(typeof page);
console.log('您的姓名是:' + uname);
console.log('您的年龄是:' + age);
console.log('您的性别是'+ sex);
console.log('据我估计,五年后,您可能' + page +'了');
运算符 operator
是用于实现赋值、比较和执行算数运算等功能的符号
算术运算符
// 取余 %
console.log(5 % 3); // 2
console.log(3 % 5); // 3
// 浮点数 算数运算里面会有问题
console.log(0.1 + 0.2);
console.log(0.07 * 100);
浮点数精度问题
表达式和返回值
表达式是由数字、运算符、变量等组成的式子
console.log(1 + 1); // 2 就是返回值
// 把右边表达式计算完毕把返回值给左边
递增和递减运算符
必须和变量配合使用
前置递增运算符
口诀:先自加1,后返回值
// 想要一个变量自己加1
var num = 1;
++num; // 类似于 num = num + 1
var p = 10;
console.log(++p + 10); // 21
++p p 这两个值是一起变化的
后置递增运算符
口诀: 先返回值,后自加
var num = 10;
num++; // 类似于 num = num + 1
var p = 10;
console.log(p++ + 10); // 20
console.log(p); // 11
小结
大多使用后置递增或递减 例如 num++,num–
比较运算符
会返回一个布尔值
=小结
逻辑运算符
返回值也是布尔值,后面开发中经常用于多个条件判断
逻辑与: 只有两侧都为true 结果才是true
逻辑或 :只有两侧都为false 结果才是false
逻辑非 :取反
短路运算(逻辑中断)
原理: 当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值
- 逻辑与:表达式1 && 表达式2
- 如果表达式1 结果为真 ,则返回表达式二
- 如果表达式1为假,则返回表达式1
console.log(123 && 456); // 456
console.log(0 && 1 + 2 && 456 * 789); // 0
// 如果有空的或否定的为假,其余是真的,如: 0 '' null undefined NaN
- 逻辑或:表达式1 || 表达式2
- 如果表达式1 结果为真 ,则返回表达式1
- 如果表达式1为假,则返回表达式2
var num = 0;
console.log(123 || num++); // 123
console.log(num); // 0
逻辑中断很重要,会影响到输出代码的值
赋值运算符
概念:用来把数据赋值给变量的运算符
var num = 10;
num += 2; // 类似于num = num + 2;
console.log(num); // 12
运算符优先级
一元运算符里面的逻辑非优先级最高
逻辑与比逻辑或优先级高
JavaScript流程控制
流程控制主要有: 顺序结构、分支结构和循环结构
顺序结构
程序会按照代码的先后顺序,依次执行
分支结构
根据不同的条件,执行不同的路径代码,从而得到不同的结果
if语句
// if的语法结构
if(条件表达式) {// 执行语句}
// 执行思路 如果if里面的表达式为true 则执行大括号里面的执行语句
执行流程
案例
// 进入网吧案例
var age = prompt('请输入您的年龄');
if(age >= 18) {
alert('进去上网');
}
ifelse双分支语句
最终只能有一个语句执行 2选1
if (条件表达式) {
// 执行语句1
} else {
// 执行语句2
}
// 如果表达式结果为真,那么执行语句1; 否则 执行语句2
执行流程
if else if语句(多分支语句)
// 多选一的过程 else if 按实际需求来写多少个
if (条件表达式1) {
// 语句1
} else if (条件表达式2) {
// 语句2
} else if (条件表达式3) {
// 语句3
}
else {
// 上述条件都不成立执行此代码
}
执行流程
三元表达式
有三元运算符组成的式子
// 如果条件表达式为true 则返回表达式1的值
条件表达式 ? 表达式1 : 表达式2 // 语法规范
var num = 10;
var result = num > 5 ? '是的' : '不是的';
console.log(result); // 是的
案例
数字补0
var time = prompt('请您输入一个0-59之间的一个数字');
var result = time < 10 ? '0' + time : time;
alert(result);
switch语句
对变量设置一系列的特定值选项时,可以用switch
// 按实际需求来写 利用表达式的值和case后面的选项值匹配
switch (表达式) {
case value1:
// 执行语句1;
break;
case value2:
// 执行语句2;
break;
default:
// 执行最后的语句;
}
注意事项
var num = 3;
switch(num) {
case 1:
console.log(1)
break;
case 3:
console.log(3)
break;
}
// 表达式经常写成变量
// num的值和case里面的值相匹配的时候是全等
// 记住写break
switch语句和if else if 语句的区别
循环结构
循环的目的:可以重复执行某些语句
for循环
// for重复执行某些代码 通常跟计数有关系
for(初始化变量;条件表达式;操作表达式) {
// 循环体
}
// 例子
for(var i = 1; i <= 100;i++) {
console.log('您好');
}
// 执行过程
// 1.var i = 1这句话只执行一次
// 2.满足条件执行循环体
// 3. 最后去执行 i++ 第一轮结束
// 4.再判断是否满足条件,直到条件不满足时,退出循环
断点测试
// for循环可以执行相同的代码
var num = prompt('请您输入次数');
for(var i = 1; i <= num;i++) {
console.log('我错了')
}
// for循环可以执行不同的代码 因为有计数器变量i的存在
for(var i = 1; i <= 100; i++) {
console.log('这个人今年' + i + '岁了');
}
// for循环重复某些相同的操作
双重for循环
for(外层的初始化变量;外层的条件表达式;外层的操作表达式){
for(里层的初始化变量;里层的条件表达式;里层的操作表达式)
{
// 执行语句;
}
}
// 可以把里面的循环看做是外层循环的语句
// 外层循环一次,里层的循环执行全部
for (var i = 1; i <= 3;i++) {
console.log('这是外层循环第' + i + '次');
for (var j = 1; j <=3;j++) {
console.log('这是里层循环第' + j + '次');
}
}
小结
while循环
while (条件表达式) {
// 循环体
}
// 当条件表达式为true 则执行循环体,否则 退出循环
var num = 1;
while (num <= 100) {
console.log('How are you');
num++;
}
// 里面也有计数器 初始化变量
// 里面也有操作表达式 完成计数器的更新 防止死循环
do while循环
do {
// 循环体
} while (条件表达式)
// 先执行一次循环体 再判断条件
// 如条件表达式为true,则执行循环体 否则退出循环
var i = 1;
do {
console.log('How are you');
i++;
} while (i <= 100)
循环小结
continue 关键字
用于立即跳出本次循环,继续下一次循环
// 退出本次循环 继续执行剩余循环
for (var i = 1; i <= 5;i++) {
if (i == 3) {
continue;
}
console.log('我正在吃第' + i + '个包子')
}
break关键字
用于立即跳出整个循环
for (var i = 1; i <= 5;i++) {
if (i == 3) {
break;
}
console.log('我正在吃第' + i + '个包子')
}
JavaScript数组
定义:存放一组数据存储在单个变量名下的优雅方式
数组的创建方式
// 1.利用new 创建数组
var arr = new Array(); // 创建一个空数组
// 2.利用数组字面量创建数组
var arr = []; // 推荐的方式
var arr1 = [1, 2, 'pink', true]; // 可存放任意数据类型
访问数组元素
索引:用来访问数组元素的序号(数组下标从0开始)
var arr1 = [1, 2, 'pink', true];
console.log(arr1[2]); // pink
console.log(arr1[3]); // true
// 如没有数组元素输出结果就是undefined
遍历数组
把数组的元素从头到尾访问一次
var arr = ['red', 'green', 'blue'];
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
数组长度
动态检测数组元素的个数
// 语法: 数组名.length
// 改进
var arr = ['red', 'green', 'blue'];
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
案例
1.计算数组的和及2.平均值
var arr = [2, 6, 1, 7, 4];
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i]; // 我们加的是数组中的元素 并不是i
}
average = sum / arr.length;
console.log(sum,average);
3.数组的最大值
var arr = [2, 6, 1, 77, 52, 25, 7];
var max = arr[0];
for (var i = 0; i < arr.length;i++) {
if (arr[i] > max) {
max = arr[i];
}
}
console.log(max);
4.数组转换为分割字符串
var arr = ['red', 'green' ,'blue', 'pink'];
var str = '';
var sep = '!';
for (var i = 0; i < arr.length; i++) {
str += arr[i] + sep;
}
console.log(str);
数组中新增元素
// 1.通过修改length长度
var arr = ['red', 'green', 'blue'];
console.log(arr.length); // 3
arr.length = 5;
// 2.修改索引号 追加数组元素
var arr1 = ['red', 'green', 'blue'];
arr1[3] = 'pink';
console.log(arr1); // 4个
arr1[0] = 'yellow'; // 替换原来的数组元素
案例
新建一个数组
里面存放10个整数 (1-10)
var arr = [];
for (var i = 0; i < 10; i++) {
// arr = i; 切记不要直接给数组赋值
arr[i] = i + 1;
}
console.log(arr);
筛选数组
大于等于10的元素选出来,放入新数组
// 方法一
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
var j = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] > 10) {
// 新数组应该从0开始 依次递增
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
// 方法二
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = []; // newArr.length 就是0
for (var i = 0; i < arr.length; i++) {
if (arr[i] > 10) {
// 新数组应该从0开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
删除指定数组元素
// 删除0
var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if(arr[i] != 0) {
newArr[newArr.length] = arr [i]
}
}
console.log(newArr);
翻转数组
var arr = ['red', 'green', 'blue', 'pink', 'purple'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i]
}
console.log(newArr);
数组排序(冒泡排序)
把一系列的数据按照一定的顺序进行排序显示
var arr = [5, 4, 3, 2, 1];
for (var i = 0; i <= arr.length - 1; i++) {
// 外层循环管趟数
for (var j = 0; j <= arr.length - i -1; j++) {
// 里层循环管交换次数
// 内部交换2个变量的值
if (arr[j] > arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr); // 1,2,3,4,5
var arr = [4, 5, 3, 1, 2];
for (var i = 0; i <= arr.length - 1; i++) {
// 外层循环管趟数
for (var j = 0; j <= arr.length - i -1; j++) {
// 里层循环管交换次数
// 内部交换2个变量的值
if (arr[j] < arr[j+1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr); // 5,4,3,2,1
JavaScript函数
函数就是封装了一段可被重复调用执行的代码块。
目的是让大量代码重复使用
function getSum(num1,num2) {
var sum = 0;
for (var i = num1;i <= num2;i++) {
sum += i;
}
console.log(sum);
}
getSum(1, 100);
函数使用
声明函数和调用函数
函数封装是把一个或多个功能通过函数的方式封装起来
// 声明函数
function 函数名() {
// 函数体
}
// 函数名一般是动词
// 函数不调用自己不执行
函数名(); // 调用函数
function sayHi() {
console.log('hi~');
}
sayHi();
案例
利用函数计算1-100之间的累加和
function getSum() {
var sum = 0;
for (var i = 1;i <= 100;i++) {
sum += i;
}
console.log(sum);
}
getSum();
函数的参数
利用函数的参数实现函数重复不同的代码
function 函数名(形参1,形参2...) {
}
函数名(实参1,实参2...);
function cook(aru) { // 形参aru可以看做不用声明的变量
console.log(aru);
}
cook('酸辣土豆丝');
cook('大肘子');
// 函数的参数可以有,也可以没有,个数不受限制
// 多个参数用逗号隔开
案例
利用函数求任意两个数之间的和
函数形参实参个数匹配
function getSum(num1, num2) {
console.log(num1 + num2);
}
console.log(1, 2); // 如果实参个数和形参的个数一致,则正常输出结果
console.log(1, 2, 3); // 如果实参个数多于形参个数一致,会取到形参的个数
console.log(1); // 如果实参个数少于形参个数一致,多于的形参定义为undefined 最终的结果是NaN
小结
函数的返回值
return语句
function 函数名() {
return 需要返回的结果;
}
函数名();
// 函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名()
// return把后面的结果 返回给函数的调用者
function getResult() {
return 666;
}
getResult();
console.log(getResult());
function cook(aru) {
return aru;
}
cook('大肘子');
console.log(cook('大肘子'));
function getSum(num1, num2) {
return num1 + num2;
}
getSum(1, 2);
案例
利用函数求两个数的最大值
function getMax(num1, num2) {
return num1 > num2 ? num1 : num2;
}
求任意一个数组中的最大值
function getArrMax(arr) { // arr接收一个数组
var max = arr[0];
for (var i = 0; i < arr.length;i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
var re = getArrMax([1, 2, 5, 9, 10]);
console.log(re);
return终止函数
1.return后面的代码不被执行
2.return只能返回一个值 结果是最后一个值
function fn(num1, num2) {
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
}
var re = fn(1, 2);
console.log(re); // 3.如需要返回多个值,可用数组
4.函数没有return时则返回undefined
break、continue、return的区别
arguments的使用
当我们不确定有多少个参数传递的时候,可以用arguments来获取
function fn() {
console.log(arguments);
// arguments对象中存储了传递的所有实参
// 遍历数组
for (var i = 0; i < arguments.length;i++) {
console.log(arguments[i]);
}
}
fn(1, 2, 3);
伪数组 并不是真正意义上的数组
1.具有数组的length属性
2.按照索引的方式进行存储
3.它没有真正数组的一些方法
案例
利用函数求任意个数的最大值
function getMax() {
var max = arguments[0];
for (var i = 0; i < arguments.length; i++) {
if(arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 2, 3));
console.log(getMax(1, 4, 6, 3));
函数案例
1. 利用函数封装,将数组翻转
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1, 3, 4, 6, 9]);
console.log(arr1); // 9,6,4,3,1
2. 对数组排序-- 冒泡排序
function sort(arr) {
for (var i = 0; i < arr.length - 1; i++) {
for (var j = 0; j < arr.length - i -1; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 5, 4, 3, 6]);
console.log(arr1); // 1,3,4,5,6
3. 判断闰年
function isRunYear(year) {
var flag = false;
if (year %4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
console.log(isRunYear(2000)); // true
console.log(isRunYear(1999)); // false
函数可以调用另外一个函数
// 函数可相互调用
function fn1() {
console.log(11);
fn2(); // 在fn1 中调用了fn2函数
}
fn1();
function fn2() {
console.log(22);
}
用户输入年份,输出当前2月份的天数
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) {
alert('当前有29天');
} else {
alert('当前有28天');
}
}
backDay();
// 判断是否是闰年的函数
function isRunYear(year) {
var flag = false;
if (year %4 == 0 && year % 100 != 0 || year % 400 == 0) {
flag = true;
}
return flag;
}
函数的2种声明方式
命名函数
// 函数表达式 语法 匿名函数
var 变量名 = function() {};
变量名(); // 调用
var fun = function() {
console.log('我是函数表达式');
}
fun(); // fun是变量名 不是函数名
// 函数表达式也可以进行传递参数
作用域
代码名字(变量)在某个范围内起作用和效果
目的为了提高程序的可靠性,减少命名冲突
js的作用域(es6)之前 : 全局作用域 和局部作用域
全局作用域: 整个script标签 或是一个单独的js文件
局部作用域: 在函数内部就是 只在函数内部起效果和作用
var num = 10;
console.log(num);
function fn() {
var num = 20;
console.log(num);
}
fn();
变量分为全局变量和局部变量
全局变量: 在全局作用域下的变量
如果在函数内部没有声明直接赋值的也是全局变量(不推荐)
局部变量: 在函数中的变量
函数的形参也是局部变量
function fun() {
var num1 = 10;
num2 = 20;
}
fun();
console.log(num2);
js没有块级作用域 (es6之前)
块级作用域 {} if {} for{}
作用域链
内部函数访问外部函数的变量,采取的是链式查找的方法
var num = 10;
function fn() { // 外部函数
var num = 20;
function fun() { // 内部函数
console.log(num); // 20
}
fun();
}
fn();
预解析
js引擎运行js分为两步:预解析 代码执行
js引擎会把js里面的var 还有 function 提升到当前作用域的最前面
代码执行 按从上往下执行
预解析分为 变量预解析和函数预解析
变量提升 把所有的变量声明提升代当前的作用域最前面 不提升赋值操作