JavaScript----js
全栈课程-------全栈工程师
前端:信息展示,普通用户浏览---前端工程师(html+css:静态页面 js:页面的交互效果)
后台:信息管理,管理员,数据库------后端工程师(php+mysql)动态页面
产品上线,部署
特别注意:
1.每条js语句结束都需要写英文状态下的;
2.js所有的标点都是英文状态下的
3.单双引号的问题:进行字符串的定义或者输出,单双引号的内容可以原样输出,互相嵌套
js的历史
网景公司:Navigator浏览器0.9版本【1994】
sun公司:javascript
js之父:Brendan Eich--10就发明了js
ESMAScript组织规范js的语法
理解(抄笔记、敲代码)+记忆
js的作用
实现网页的交互作用
进行数据验证
操作cookie、session
小游戏:贪吃蛇、打字游戏、扫雷
与后台的node.js
......
js的组成
ECMAScript------js的基础语法
BOM------Broswer Object Model 浏览器对象模型
DOm----Document object Model 文档对象模型
js的特点
基于对象和事件驱动的松散型、解释性语言,寄宿于浏览器,单线程异步
JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言内置支持类型,他的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,用来给html网页增加动态功能。
js的报错
-
语法错误:Uncaught SyntaxError
低级错误,执行前全部扫描一遍,如果有语法错误,所有js代码错误,所有js代码都不执行
-
逻辑错误:
在js代码执行时发生,不可避免,出错的代码不会执行,之前的代码会正常执行
js的引入
注意:外部引入和嵌入式不能混合使用,一个srcipr中不能既有src又有js代码,但可以有多个srcipt标签共同作用
-
外部引入
<srcipt src="js/index.js"></srcipt>
-
嵌入式
<srcipt>直接写js代码</srcipt>
-
在a的href中
<a href="javasrcipt:alert('1')">我是a</a>
form表单
-
事件后面
<div class="box" onclik="alert('1')">
[]\]
</div>
js的调试工具
alert()------窗口弹出框
console.log()--------在控制台输出
document.write()-------写入的页面(可以识别标签)
prompt()-----输出弹框
confirm()----确认取消框
变量
可以变化的量。数据存储的容器
-
变量的声明
声明变量,用关键字var
没有用var声明的变量,叫全局变量
不要用var多次声明同一个变量
变量提升:一个变量先使用后赋值,默认为undefined(变量提升)
js执行时浏览器会进行预解析,var声明的变量以及function函数会进行变量提升
-
变量的赋值
-
可以在声明的同时赋值
var num = 1;
-
可以先声明,后赋值
var num1,
num1 = 1; -
一次性声明多个变量(用,隔开),然后分别赋值
var num2,num3;num2 = "123"; num3 = "123";
-
一次性声明多个变量的同时赋值
var num4 = 1, num5 = 2;
可以多次赋值,后面的会覆盖前面的
一个变量没有声明就使用,会报错(该变量 is not defined)
未赋值的变量默认为undefined
3.变量命名时注意的:
名字都是以数字、下划线、字母与$组成,数字不能开头
常用的命名方式:要有意义,见名知意(英文翻译)、驼峰命名法、首字母大写
避免与关键字与保留字冲突
区分大小写:
-
数据类型
初始数据类型和引用数据类型的区别:分别放在栈区和堆区,栈区和堆区的区别:栈区放置变量和函数名,执行完程序自动删除,堆区放置引用的数据,可以自己删除,也会被js的垃圾回收处理删除
初始数据类型
-
数值型-----typeof:number
整数
小数
负数
科学计数法(3.2e5)
二进制0b开头、八进制0开头、十进制、十六进制0x开头
最大值(Number MAX_VALUE)
最小值(Number MIN_VALUE)
-
parseint 从首位开始转化为整型。,如果字符串的第一个字符不能转化为数字(后面跟着数字的正负号除外),返回NaN 123a456 转换成123
null\undefined/bolen--->NaN
-
NaN (not a number)-----不是一个数 Nan==NaN (false) Number.isNAN(NaN)
if(Number.isNAN(num) 如果number是NaN。返回true
-
字符串--------typeof:String
单双引号里面的内容,双引号里面嵌套单引号,单引号里面嵌套双引号
-
数值型字符串
var str2 = "12234";
-
非数值型字符串
var str = "abcdef";
var str1 = "cdes'qwe'qq";
-
-
布尔值--------typeof:Boolean
var b = false;
var c = true; -
undefined--------typeof:undefined
未定义----只声明未赋值的变量默认是undefined,先使用后声明的变量为undefined
var cc;
console.log(cc)//undefined
console.log(dd)//undefined
var dd = 10; -
null--------typeof:Object
清空对象
复合数据类型
-
对象/object--------typeof:Object
函数、数组
运算符
算数运算符
-
算数加: 算数加/字符串拼接
!!任何数据类型与字符串相加,结果都是字符串
-
/ * -
算数的减乘除,得到的结果一定是number类型
如果不能运算(字符串/字符串),得到的结果为NaN
如果是数值型字符串,会默认转化为数值型
% 取余得到的结果
-
++/-- 自增
如果++/--在前,先自增再运算
如果++/--在后,先运算后自增
关系运算符----得到的结果为布尔值
<= < > >= == != === !==
数值型与数值型比较,直接比大小
数值型与非数值型字符串比较,不能比较大小,直接返回false
数值型与数值型字符串比较,先把数值型字符串转化为数值型,再依次比较大小
字符串与字符串比较,依次比较ASCll码的大小
-
== === != !==
== 判断数值是否相等
=== 判断数值与数据类型相等
PS:= 赋值运算
赋值运算符
= += -= *= /= %=
逻辑运算符
-
&& 逻辑与
当所有表达式都为真时,结果为真;只要一个为假,结果为假
-
|| 逻辑或
只要一个为真,结果为真;所有表达式为假,结果为假
-
! 逻辑非
取反,原来表达式为真,结果为假;原来表达式为假,结果为真
特殊的几个假值:0 NaN false undefined "" null
======================================================================
赋值时,会发生短路运算:
&&会找第一个假值,如果没有会找第二真值;
||会找第一个真值,如果没有会找第二假值
运算符的优先级
let x,y,z
x=1+3<2|| true 输出为true || 小于 = 小于 < 小于 +
=======================================================================
表达式1 | 表达式2 | && | || | ! |
---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | flase |
false | false | false | false | true |
false | true | false | true | true |
三元运算符
一元运算符:+(正数) -(负数) ++(自增) --(自减) new实例化对象 delete删除对象属性或变量
(表达式1)?(表达式2):(表达式3)
如果表达式1成立,执行表达式2,否则,执行表达式3
特殊运算符
,声明多个变量的时候进行分隔
() ---- 提高运算的优先级/函数调用
\转义
=====================================================
运算的优先级:
赋值运算优先级最低,()优先级最高
赋值运算时,从左往右的顺序执行
其他运算,从左往右的顺序执行
====================================================
流程控制
代码执行的顺序
1.顺序结构
按照顺序依次执行
2.分支结构/选择结构
-
单路分支
if(条件表达式){
//条件成立要执行的语句
} -
双路分支
if(条件表达式){
条件成立要执行的代码
}else{
条件不成立要执行的代码
} -
多路分支
if(条件表达式1){
执行语句1
}else if(条件表达式2){
执行语句2
}else if(条件表达式2){
执行语句2
}else{
以上条件不成立,输出的语句
}
-
嵌套分支
if(表达式1){
if(表达式){
执行语句1;
}else{
执行语句2;
}
} -
switch分支
// switch(表达式){
// case "表达式可能的值":如果是该值要执行的语句;
// break(终止后面程序的执行)
// }
//案例1:测试星期几
var week = prompt("亲输入内容");
switch(week){
case "1":alert("星期一");
break;
case "2":alert("星期二");
break;
case "3":alert("星期三");
break;
case "4":alert("星期四");
break;
case "5":alert("星期五");
break;
case "6":alert("星期六");
break;
case "7":alert("星期日");
break;//终止,结束
//其余所有情况都不满足时要执行的代码
default:alert("输入错误")
}if和switch的不同点:
if是连续性数据的区间
switch是离散型数据
-
if(括号里可以写)
条件表达式
number 除了0以外都是true 0是falsestring “”空字符串是false,其他都是true
undefined/null在转换下会变成NaN
bolean true/ false
3.循环结构
-
for循环
for (var i = 0; i < 10; i++) {
//循环体
console.log(i)
}
//语法
for(表达式1;表达式2;表达式3){
循环体
}
表达式1:变量的初始值
表达式2:进行循环的条件 i<10
表达式3:步进值 i++/i--
// 执行过程:
表达式1--->表达式2(判断是否满足当前的条件)--->如果满足,执行循环体--->表达式3(让变量自增)如果 不满足,直接跳出循环体 -
while循环
当条件满足时,在进入循环体
适用于:只知道循环的条件,不知道要循环几次
var num = 6;
while(num<10){
console.log(1)
num++;
} -
do while循环
先执行循环体,在判断条件是否满足
不管条件是否满足,总会先执行一次循环体
适用于:只知道循环的条件,不知道循环的次数
do while{
//循环体
}(条件)
数组:可以存储一组或一系列相关变量的容器
应用场景:
解决大量相关数据的存储
便于程序的开发和使用
清空数组:arr.length=0
注意事项:可以存储任何数据类型的数据
长度可变
数组下标从0开始,如果指定长度没有赋值则输出undefined
定义数组:直接赋值/先声明后赋值
var arr = [];
var newarr = new Array(里面的是数组的长度);new一个实例化对象
//数组中可以存储任何数据类型的数据如下:
var arr = [1,"234",undefined,null,false,[]];
访问数组
访问数组用下标,从0开始
可以越界访问,越界访问的值默认为undefined
自定义数组的长度,未赋值的位置为undefined
数组的长度,arr.length
与下标的关系:比下标多一
数组的遍历---得到数组的每一个元素
for of更加适合遍历数组,遍历的是数组的value,不能遍历对象
for in 更适合遍历对象 ,遍历的是数组的index
1.一维数组
let arr1=[1,2,3]
let arr2
arr2=arr 直接赋值这叫传址 ar r1再次发生变化 arr2 也变化
遍历赋值 叫做浅拷贝 arr1变化 不影响arr2
var arr5=["fas",23, 45,"asd"];
for(var i=0;i<arr.length;i++){
console.log(arr5[i]);
}
2.二维数组的遍历
浅拷贝是一个传址,也就是把a的值赋给b的时候同时也把a的址赋给了b,当b(a)的值改变的时候,a(b)的值同时也会改变
深拷贝:深拷贝是指,拷贝对象的具体内容,二内存地址是自主分配的,拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样,俩个对象页互相不影响,互不干涉
外循环控制的是二维数组的长度,其实就是一维数组的个数行数。
内循环控制的是一维数组的长度,每一行,一维数组元素分别的个数。
// 求二维数组所有元素的和
var arr9 = [[1,1],[1,1],[1,1]];
function arr(arr1){
var plus=0;
for (var i = 0; i < arr1.length; i++) {
for (var j = 0; j < arr1[i].length; j++) {
plus +=arr9[i][j];
}
}
return plus;
}
console.log(arr(arr9))
for(let i in arr9){
console.log(i);
console.log(arr9[i])
}
//forEach
let res = arr9.forEach(function(val,index){
console.log(val,index)
})
let res = arr9.forEach(function(val,index)=>{
console.log(val,index)
})
函数
函数的作用
封装具有特定功能的代码段,代码段可以重复使用
函数的定义:封装具有特定功能的代码段,代码段可以重复使用
-
用function关键字定义--会优先解析,可以声明之前调用函数
形参:形式参数,在声明函数时括号里面的参数 作用 :接收实参
实参:实际参数,在调用函数时括号里面的参数 作用:传递参数
参数问题:1.参数可以是任何的数据类型
2、参数的个数(默认要一一对应)
如果形参>实参,剩余形参为undefined
如果实参>形参,剩余实参可以在arguments对象中寻找
function funName(形参1,形参2,...){
//里面写函数体
return;
} funname(实参1,实参2) -
通过字面量的函数,匿名函数--只能先定义后调用,不能再定义之前调用,否则,会报错
var a=function(){
//函数体
return;;
}a()
匿名函数
(function(){
console.log(123)
})() -
通过实例化Function得到一个函数
var fn = new Function("形参","函数体")
fn()
函数的调用--
函数名();
写在事件中
-
自调用
(function aa(){
alert(num)
})(2);
函数的参数
可以让函数更加灵活
形参:定义函数时()中的的参数,相当于变量名
实参:调用时函数里面的参数,相当于变量值
函数的重载:通过参数的类型或值得不同,执行不同的函数体
-
关系
实参=形参:--对应
实参<形参:多余的形参默认是undefined
实参>形参:多余的实参用arguments处理
也可以...res接受
arguments:每个函数都有的属性,用来接收所有的的实参,把实参放在类似于数组的对象中
...res:接受多余的实参,放在一个数组中
function aa(num,num1,...num2){
console.log(num,num1,num2)//1 2 (9) [3, 5, 8, 9, 2, 45, 5, 5, 5]
}
aa(1,2,3,5,8,9,2,45,5,5,5)
-
参数的默认值
-
if else
function fn(num,flag){
if(flag==undefined){
flag="+";
}else{
flag=flag;
}
if(flag=="<"){
//从大到小排序
}else if(flag==">"){
//从小往大排序
}
} -
三元表达式
flag = (flag==undefined)?("+"):(flag)
-
逻辑表达式
flag = flag||"+";
-
ES6中,直接写在形参的最后,如果该值为假,才会促发
function fu(num,flag="+“){
//函数体
}
-
函数的返回值
-
作用:
终止函数的运行
给函数一个返回值
可以返回任何数据类型的数据,函数返回的结果是调用函数的结果
每个函数都只能有一个返回值,如果有多个,就是在分支结构中
原则上,每个函数都有一个返回值,如果没有,调用函数的结果undefined
作用域
全局作用域/全局变量:
在全局或任何地方都可以起作用的变量,任何地方都可以修改
通过var在外部定义的变量
没有用var声明但赋值的变量
局部作用域/局部变量:
定义在函数内部的变量
函数的形参
用let声明的块级作用域的变量
块级作用域:{}
作用域链:
我们可以把作用域看成是用链条连接起来的,这样能够使得函数能有序的进行运行
里层函数可以访问外层函数的变量,但是外层函数不可以访问里层函数的变量
几种特殊函数
递归函数
自己调用函数
案例
1.深拷贝
2阶乘:1的阶乘为1 0的阶乘为1
//阶乘 5! = 5*4*3*2*1
// 5! = 5*4!
// 4*3!=24
// 3*2!=6
// 2*1!=2
// 1!=1
// 0!=1
//找规律n! = n*(n-1)!
//找界定条件 0!=1 1!=1
function jc(num){
if(num == 1||num == 0){
return 1;
}
return num*jc(num-1);
}
alert(jc(6))
斐波纳契数列 fb(num-1)+fb(num-2)的阶乘为1
F(n)=F(n-1)+F(n-2)
F(5)=F(4)+F(3) 5
F(4)=F(3)+F(2) 3
F(3)=F(2)+F(1) 2 function fb(num){
if(num == 1||num==2){
return 1;
}
return fb(num-1)+fb(num-2);
}
alert(fb(10))
回调函数--作为参数的函数
function main(num1,num2,collback){
console.log("我是主函数")
collback();
return num1+num2;
}
function fn(){
console.log("我是回调函数");
}
let arr = [1,2,3];
main(1,2,fn)
四则运算
function jia(a,b){
return a+b;
}
function jian(a,b){
return a-b;
}
function cheng(a,b){
return a*b;
}
function chu(a,b){
return a/b;
}
function fnn(a,b,fn){
return fn(a,b)
}
console.log(fnn(10,30,cheng))
高阶参数
//num的阶乘
function fn(num){
if(num==0){
return 1;
}
if(num==1){
return 1;
}
else{
return num*fn(num-1)
}
}
console.log(fn(5))
//数组 深拷贝
let arr=[[1,2],[5,8],[1,[8,77,[99,33]]]];
function aa(arr){
for(let i=0;i<arr.length;i++){
if(typeof arr[i]!="object"){
newarr[i]=arr[i]
}else{
newarr[i]=aa(arr[i])
}
}
return newarr
}
console.log(arr)
闭包函数
定义:当两个函数发生嵌套关系时,内层函数使用外层函数的变量,并在全局环境下调用内层函数 保护内部变量不别清理掉
箭头函数--ES6新增的函数的表现形式
1.形参=>返回值
let sum = num=>num;
console.log(sum(1))
2.(形参1,形参2)=>返回值
//(形参)=>返回值
let sum=(num,num1)=>num+num1;
console.log(sum(1,2))
3.(形参1,形参2)=>{ 函数体; return;}
let fu = (num1,num)=>{
if(num1%2=0){
num1=1;
}
return;
}
内置顶层函数
‘
ECMAscript 自带的函数,ECMAscript将我们常用的一些功能封装起来,我们不需要知道他是怎么实现
的,只需要知道怎么调用即可。.js内部定义的,在任何地方可以调用的函数
escape() 将非字母、数字字符进行编码
unescape() 对编码的字符串进行解码
-
Number() 转换成数值类型
布尔值-->false--0 true---1 字符串:数值型的字符串---直接转换 非数值字符串---NaN
undefined-->NaNnull--->0
String() 转换成字符串类型
-
Boolean() 转换成布尔类型
null、undefined、0、""、NaN 、false为假,其他都为真
!!!!!!!parseInt() 将字符串转换为整型
parseFloat() 转换为浮点数数:去掉一些没有意义的0
-
tofixed(n)给数字后面加小数点后位数
let num=12 ; console.log(num.toFixed(2))---12.00
-
isNaN() 判断是不是NaN
如果是NaN,返回true,否则,返回false
强制数据类型转化:number、Boolean、string、parseint、parsefloat
隐式数据类型转化: if() 2+"5";运算符、while
除了强制类型转换(能看到的),其他都是隐式数据转换
引用函数的类型是function
let和const
let:块级作用域
ES6中新增的声明变量的关键字,用法同var
-
不同点
let不存在变量提升
let不能重复声明同一个变量,可以重复赋值
let可以识别块级作用域,成为局部变量,只在当前的块级作用域起作用
conat
ES6新增的关键字,用来声明常量(不变的量)
只能在声明的同时赋值
一般常量的名字全部大写
常量不能重复赋值
可以识别块级作用域
只在当前的块级作用域起作用
不存在变量提升
对象
new
使用new操作符调用构造函数时,会经历4个阶段
1.创建一个对象2.将这个对象的proto成员指向了构造函数对象的prototype成员对象,这是最关键的一步3.将构造函数的作用域赋给新对象,this就是新对象 4.返回新对象
var zhangsan = {};
zhangsan.__proto__=person.prototype;
person.call(zhangsan);
return zhangsan;
对象的创建:
-
通过构造函数创建类-------工厂函数
function Computer(yanse,jiage){
this.color = yanse;
this.price = jiage;
this.study = function(){
console.log("跶游戏")
}
}//通过new一个类,实例化一个对象
let dell =new Computer("red","9999");
console.log(dell)
//dell.color = "yellow";
//dell.price = "10000"; -
通过class关键字创建类
class Person{
//构造函数
constructor(arms,eye){
this.arms = arms;
this.eye = eye;
this.study = function(){
console.log("街道口");
}
}
}
let zhangsan = new Person(2,2);
console.log(zhangsan); -
json(javascript object notation)直接创建对象 轻量级的数据交换格式
{
name:"李四",
age:15,
key:value
}
let mi = {
name :"小米手机",
color:"red",
price:318,
watch:function(){
console.log("看电视");
return 0;
},
cpu:"123"
}
console.log(mi.cpu)
console.log(mi)proto 每个对象都有的属性,用来继承,指向它的构造函数的原型
对象的遍历
查看某个对象的构造函数,通过.constructor
console.log(mi.constructor)
判断某个对象是不是属于某个构造函数 instanceof如果是,返回true;否则,返回false
console.log(zhangsan instanceof Person)
每一个函数都有一个属性.prototype
console.log(zhangsan.constructor.prototype)
每个对象的proto指向构造函数的prototype
console.log(zhangsan.__proto__=zhangsan.constructor.prototype)//true
字符串对象
属性 length //对象方法
-
查询:
charAt //获取字符串某个位置的值(0~n)
charCodeAt()//获取字符串的ASCII
search //只能配合正则使用
match //某个字符在字符串的位置情况,返回值是一个数组,它可以配合正则使用
indexOf(string) //获取某个字符在字符串首次出现的位置,如果没有找到返回值为-1
lastIindexOf(string) //获取某个字符在字符串最后出现的位置,如果没有找到返回值为-1
replace("string","string") //替换字符串中的某个字符,第一个参数为要替换的参数,第二参数为替换后的参数,可以配合正则使用
-
截取:
slice(int,int) //截取字符串中的一段,两个参数都是代表位置,从第一个参数的的位置截取到第二个参数的位置,包含第一个不包含第二个,如果只有开始的位置将一直截取结束;如果是负数,将倒数
substr //截取字符串中的一段,第一个参数为开始截取的位置,第二个参数为截取长度
substring(int,int) //和slice类似,但它不接收负数
-
其他:
toLowerCase //把里面的大写字母转化为小写字母
toUpperCase //把里面的小写字母转化为大写字母
split(string) //把字符串以某种分割符分割为数组,可以配合正则使用
trim //去掉字符串中的前后空格
concat //拼接
数组对象
concat()---数组的拼接,返回新数组,原数组不会改变,参数:可以传一个或者多个元素,也可以是其他数组字符串对象
-
增删
unshift// 给数组的最前面添加一个或多个元素,返回新数组,原数组发生变化.参数:要添加的元素
shift----删除数组中的第一个元素,返回删除的元素,原数组发生变化,参数:无
push-----给数组添加一个或多个元素,返回新数组的长度,原数组发生变化,参数:要添加的元素
pop------删除数组中的最后一个元素,返回被删除的元素。原数组发生变化,是删除之后的数组,参数:无
slice-----截取数组的一部分,返回被截取的部分,原数组不变,参数:参数1.截取的开始位置,参数2.截取结束的位置,不包括
-