js写入的方式有两种
①引入外部的js—即引入index.js文件—-常用
②在html文件中写script
数据类型
弱类型自动推断类型
数字(number)
字符串(string)
布尔型(boolean)
null(空)&undefined(未定义)
注意:空和未定义不是一回事
null是有值但为空,undefined是根本没有被定义
定义变量—var&let(const定义常量)
弱类型—不需要申明这个变量的类型,统一用var
<script>// 数字var num=3;var money=20.5;// 字符串var str='hello';// 布尔型var flag=true;// 空var nul=null;// 未定义var person;console.log('hello js')console.log(num)console.log(money)console.log(str)console.log(flag)console.log(nul)//nullconsole.log(person)//undefined</script>
注意:建议js中使用‘ ‘;
用var定义可以重复使用相同的名字,但是会被后者覆盖;用let定义不能重复,会报错,但是使用变量可以重新赋值;用const定义的变量不能被修改,且定义变量时必须要初始化。
// 数字let nums=3;let nums=618;console.log(nums)//会报错nums=255;var num=100;var num=200;console.log(num)//输出结果:200
运算符
算术运算符( + - * / % )
两边都先转换为number,再运算// + - * / %var a =3;var b = 3.3;var c = 4;console.log(a/c);//0.75console.log(a*b) // 9.899999999999999console.log(b/a) // 1.0999999999999999console.log(c%a) // 1
比较运算符( >,<,==,>=,<=,!= )
两边都先转换为number,再比较,返回的是 booleanvar a = truevar b = 1;console.log(a==b) // trueconsole.log(a=="1") //true 两边都先转为number
//在js中判断变量相等var a = '5';var b = 5;// 只要求内容相等,不要求数据类型相同console.log(a == b); //true// 要求内容相等,要求数据类型相同console.log(a === b); //false
注意: null == undefined
null 和 undefined 不能转化为其他值** Number(""),Number(" "),Number(null) => 输出 0**
// Number(""),Number(" "),Number(null) => 输出 0console.log(false == ""); // trueconsole.log(true == 1); // trueconsole.log(null == undefined); // trueconsole.log(undefined == false); // falseconsole.log(1 == "1"); // trueconsole.log(null == false); // false/* 1.只有有一边为 boolean 先两边转为number2.一边为string,一边为number,先将两遍转为number// 两边都先转为number3. null == undefined4. null 和 undefined 不能转化为其他值*/
逻辑运算符( &&,||,! )
两边都先转换为boolean,再判断,返回的是 boolean值```javascript // && 逻辑与 两个为true,结果才为true // || 或 只要有一个为true,结果就为true // ! 非
console.log(3>2 && 4>3) // true && true 结果为true console.log(3>2 && 4<3) // true && false 结果为false
console.log(11>5 || 3<4) // true || false 结果为true
console.log(!(3>4)) //!false 结果为true
```javascript/* var a = 0;var b = 1;console.log(a && b);//0console.log(b && a);//0console.log(a || b);//1console.log(b || a);//1 */var a = 3;var b = 1;console.log(a && b);//1console.log(b && a);//3console.log(a || b);//3console.log(b || a);//1
或运算的注意点
|| 有一边为true,结果就为 true,遇到true就会返回var b = 0 || "abc"var c = "abc" || 1;var d = 0 || NaNconsole.log(b) // abcconsole.log(c) // abcconsole.log(d) // NaN
与运算的注意点
**两边都为true,结果才为true 遇到false的情况,直接返回**console.log("abc" && 10) // 10console.log(0 && "abc") // 0
三元运算符
// true 输出问号后面的第一段语句// false 输出问号后面的第二段语句var a = (4>5)?"4大于5":"4小于5";console.log(a)
赋值运算(+=,-=)
// +=,-=var a = 2;//a=a+4;a+=4;var b = 4;b-=4; // b=b-4;console.log(a) // 6console.log(b) // 0
数组—三种方式
①var array=Array();
②var array=new Array();
③var array=[1,2,3];//数组var array=Array();array[0]=1;// console.log(array);//[1]array[1]=618;console.log(array);//[1,618]var array=new Array();array[0]=618;console.log(array);//[618]var array=[1,2,3];console.log(array);//[1,2,3]array[8]=8;console.log(array);//[1, 2, 3, empty × 5, 8]for(var i=0;i<array.length;i++){console.log(array[i])}
方法—直接用function+方法名(){方法体}
注意:
如果方法有返回值,直接在方法体中加入return;如果没有则不需要在意。
参数不需要写类型//方法1function plus(a,b){console.log(a+'+'+b+'='+(a+b))//1+4=5return a+b;//有返回值}var c=plus(1,4)console.log(c)//5//方法2var minus=function(a,b){console.log(a+'-'+b+'='+(a-b))//1-4=-3return a-b;//有返回值}minus(8,4);var sc=minus(1,4)console.log(sc)//-3//方法3;(function(a,b){console.log(a+'-'+b+'='+(a-b))//8-8=0return a-b;})(8,8)
对象(Object)
注意:
js中{ }表示对象;[ ]表示数组。//对象var dog=new Object();//属性dog.color='red';// console.log(dog)//color: "red"//方法dog.eat=function(){console.log('我要吃骨头')}dog.eat();console.log(dog)
构造方法
//构造方法function User(name,age){//this相当于创建的对象userthis.name=name;this.age=age;}var user=new User('嘎嘎',27);// console.log(user)//User {name: "嘎嘎", age: 27}//添加方法user.eat=function(){console.log('干饭啦')}//调用方法user.eat();console.log(user)
json
//构造方法//一个人养了一条狗function User(name,age,dog){//this相当于创建的对象userthis.name=name;this.age=age;this.dog=dog;}function Dog(name,color){//this相当于创建的对象userthis.name=name;this.color=color;}var dog1=new Dog('teddy','green');var user=new User('嘎嘎',27,dog1);// console.log(user)//User {name: "嘎嘎", age: 27}//添加方法user.eat=function(){console.log('干饭啦')}//调用方法user.eat();console.log(user)
数组中可以定义多个对象 ```java //构造方法
//一个人养了一条狗function User(name,age,dog){//this相当于创建的对象userthis.name=name;this.age=age;this.dog=dog;}function Dog(name,color){//this相当于创建的对象userthis.name=name;this.color=color;}
//定义多条狗var dogs=[{name:'teddy',color:'red'},{name:'teddy2',color:'red'}]console.log(dogs)//定义多个人var users=[{name:'王嘉尔',age:27,hobbies:['唱歌','跳舞'],dog:{name:'teddy',color:'gray'},eat:function(food){console.log('多吃点'+food)}},{name:'白敬亭',age:27}]// console.log(users[0])console.log(users[0].hobbies[1])//跳舞users[0].eat('肉');//多吃点肉//添加一个游泳的方法/* person.swmming=function(){console.log('我会游泳')} *///遍历hobbiesfor(var i=0;i<users[0].hobbies.length;i++){console.log(users[0].hobbies[i])}
**方法中可以传入方法**```javavar f1=function(){console.log(111)}var f2=function(f){f();}f2(f1);//111
判断与循环—与java一样
注意:undefined——false;
0———————false;
null——————false;
false—————-false;
‘ ‘(空字符串)—-false
除此以外都是真——[](空数组)—true;{}(空对象)—true
if语句(略)
switch语句(略)
循环数组(略)
遍历对象属性
注意:
获取对象属性的方法:对象名.属性名;对象名[‘属性名’];对象名[key]
//获取pig的值的方式var pig={name:'teddy',color:'red'}//第一种console.log(pig.name);//teddy//第二种console.log(pig['name']);//teddyconsole.log(pig.color);//red//遍历for(var key in pig){//拿到pig对象的属性console.log(key);//name,color//获取值--第三种console.log(pig[key])//name teddy color red}
遍历类数组
// 类数组var obj={0:123,1:234,2:456,length:3}console.log(obj[0])//遍历for(var i=0;i<obj.length;i++){console.log(obj[i])//123,234,456}
内置参数—arguments
arguments表示传入的参数(可变参数)—本质上是一个数组
//内置参数function name(){//arguments-代表传入的参数(可变参数)--//本质是一个数组// console.log()var sum=0;for(var i=0;i<arguments.length;i++){// console.log(arguments[i])sum+=arguments[i];}return sum;}var i=name(1,2,3,4)console.log(i)//10
内置对象
数组对象
数组的常用方法
//数组对象let arr = [1, 2, 34, 56];//数组中有没有6console.log(arr.includes(6)); //false//连接console.log(arr.concat([2, 3, 4])); //[1, 2, 34, 56, 2, 3, 4]//获取数字对应的下标console.log(arr.indexOf(2)); //1//用-连接,返回的是一个字符串,jion方法不传参数默认的是,console.log(arr.join("-")); //1-2-34-56//从尾部添加4,返回的是新数组的长度console.log(arr.push(4)); //5console.log(arr); //[1, 2, 34, 56,4]//pop方法是从尾部删除元素console.log(arr.pop(4)); //弹出4console.log(arr); //[1, 2, 34, 56]//shift方法是从首位删除元素console.log(arr.shift()); //删除1console.log(arr); //[2, 34, 56]console.log(arr.shift(5)); //删除2console.log(arr); //[34, 56]//unshift方法从首位开始添加元素console.log(arr.unshift(618)); //添加618console.log(arr); //[618,34, 56]
数组的排序
//数组的排序function sort(array, fn) {for (var i = 0; i < array.length - 1; i++) {for (var j = 0; j < array.length - 1 - i; j++) {if (fn(array[j],array[j+1])>0) {var temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;}}}}var array=[1,2,8,4,3,2];console.log(array);//[1, 2, 8, 4, 3, 2]/*console.log(array);//[1, 2, 8, 4, 3, 2]sort(array);console.log(array)//[1, 2, 2, 3, 4, 8]*/sort(array,function(num1,num2){//num1>num2,前面的比后面的大,就交换位置--正序// return num1-num2;//[1, 2, 2, 3, 4, 8]正序//num2>num1,后面的比前面的大,就交换位置--倒序return num2-num1;//[8, 4, 3, 2, 2, 1]})console.log(array)
filter()方法和map方法
//filter()--过滤--将数组中元素>10的过滤出来var myArr = [1, 2, 4, 5, 12, 2, 14, 5];console.log(myArr.filter(function (a) {return a > 10;})) //12,14function filter(array, fn) {var temp=[];for (var i = 0; i < array.length; i++) {if(fn(array[i])) {temp.push(array[i])}}return temp;}var array = [1, 2, 8, 4, 3, 2];console.log(array); //[1, 2, 8, 4, 3, 2]var f = filter(array, function (num) {return num <= 5; //[1, 2, 4, 3, 2]})console.log(f)
//map()方法--映射,将一个数组中的元素映射成一个新的元素function map(array, fn) {var temp=[];for (var i = 0; i < array.length; i++) {temp.push(fn(array[i]))}return temp;}var array = [1, 2, 8, 4, 3, 2];console.log(array); //[1, 2, 8, 4, 3, 2]var f = map(array, function (num) {return num +5; //[6, 7, 13, 9, 8, 7]})console.log(f)
字符串对象
数值对象
数学对象
日期对象
DOM编程—document—文档对象模型
元素节点
属性节点
BOM编程—browser—浏览器对象模型
常用方法
回调函数—之前的filter和map里面使用了
setTimeout—延时定时器&&setInterval—周期性定时器
//一次性定时器--延时setTimeout(function(){//延时一秒钟产生一个20-30之间的随机数console.log(Math.random()*10+20)},2000)//周期性定时器setInterval(function(){console.log(Math.random()*10+20)},1000)console.log('before');setTimeout(function(){//延时一秒钟产生一个20-30之间的随机数console.log('middle');},2000)console.log('after');结果:before-->after-->middle(js是单线程,控制台会依次输出,当执行到定时器,先执行后面的after,当时间到了就输出middle)var num=10;setTimeout(function(){//延时一秒钟产生一个20-30之间的随机数console.log(num);},2000)num=15;结果:15
浏览器自带小型数据库—常用
history
事件
定义事件的三种方式—第一种最常用—单击事件—click
//事件方式(1)--常用//拿到div--添加点击事件var btn=document.querySelector('.item');btn.addEventListener('click',function(){//弹窗// alert(1);//重置btn.setAttribute('class','newitem')})//第二种方式btn.onclick=function(){alert(1);}//第三种方式--在div中添加onclick=""function fn(num){alert(num);}
双击事件—dblclick
消除事件
事件分类
鼠标事件
键盘事件
表单事件
(文档、浏览器)对象事件
小案例
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>标签的主题</title><style>*{margin: 0;padding: 0;}.nav{list-style-type: none;width: 1005px;height: 50px;text-align: center;border-bottom: 1px solid black;margin: auto auto;}.item{width: 200px;height: 50px;list-style: none;float: left;background-color: green;line-height: 50px;border-right: 1px solid black;}.item:hover{cursor: pointer;background-color: mediumturquoise;}.active{background-color: pink !important;}</style></head><body><ul class="nav"><li class="item" data-index="1">服装</li><li class="item" data-index="2">鞋子</li><li class="item" data-index="3">电子产品</li><li class="item" data-index="4">裤子</li><li class="item" data-index="5">视频</li></ul></body><script src="./js/event.js"></script></html>
//添加事件--index2中的livar lis=document.querySelectorAll('.item');for(let i=0;i<lis.length;i++){lis[i].addEventListener('click',function(){for(let i=0;i<lis.length;i++){lis[i].className="item";}this.className='item active';})}//给ul添加事件var ul=document.querySelector('.nav');ul.addEventListener('click',function(event){event.target.className='item active'})
事件冒泡与事件捕获—-先捕获再冒泡
this关键字
this的使用
注意:任何的方法里面的this都指向调用的这个方法的实例对象
//this/* let dog={name:'teddy',say:function(){//this指的是dog对象console.log('my name is:'+this.name);//my name is:teddy}}dog.say(); *//* function fn(){setTimeout(function(){//this指的是window//注意:在window中不要使用name,因为window自带有name属性,是空串console.log(this.name);},1000)}fn(); */let dog={name:'teddy',//say是dog调用的say:function(){/* setTimeout(function(){//funcion是window调用的,this指的是windowconsole.log('my name is:'+this.name);//my name is:},1000) *///使this.name=teddy,在function里面定义//that指的是dogvar that=this;setTimeout(function(){console.log('my name is:'+that.name);//my name is:teddy},1000)}}dog.say();
改变this指向call,apply,bind
/* let dog={name:'teddy',//say是dog调用的say:function(){//让this指向别的--call中的对象,打印结果是call对象中的属性值var that=this;setTimeout(function(){console.log('my name is:'+that.name);//my name is:erha},1000)}}// dog.say.call({name:'erha'});// dog.say.apply({name:'erha'});//打印结果--my name is:erha//bind有返回值var fn=dog.say.bind({name:'erha'});//打印结果--my name is:erhafn(); */let dog={name:'teddy',//say是dog调用的say:function(a,b){//让this指向别的--call中的对象,打印结果是call对象中的属性值var that=this;console.log(a,b);setTimeout(function(){console.log('my name is:'+that.name);//my name is:erha},1000)}}dog.say.call({name:'erha'},12,23);//12 23 my name is:erha//apply要传数组dog.say.apply({name:'erha'},[45,67]);//45 67 my name is:erhavar fn=dog.say.bind({name:'erha'},89,34);//89 34 my name is:erhafn();
作用域
//函数作用域/* function fn(){var num=3;}//外面的作用域不能访问里面的作用域console.log(num);//Uncaught ReferenceError: num is not defined *//* //块作用域//用var定义变量不会形成块作用域{var num=3;}{var num=4;}console.log(num);//4 *//* //用let定义变量会形成块作用域{let num=3;}{let num=4;}console.log(num);//Uncaught ReferenceError: num is not defined *//* for(var i=0;i<10;i++){}// console.log(i);//10for(;i<20;i++){console.log(i);//10 11 ... 19} *//* //let不能重复定义;let定义的变量能形成独立的作用域for(let i=0;i<10;i++){}// console.log(i);//event.js:180 Uncaught ReferenceError: i is not defined */var num1=10;function f1(){var num2=11;function f2(){var num2=12;console.log('f2-->'+num2);//12}f2();console.log('f1-->'+num2);//11}f1();// console.log('out'+num2);//event.js:195 Uncaught ReferenceError: num2 is not definedconsole.log('out'+num1);//10
变量和函数声明提升
/* console.log(a);//undefined--a声明了没有被定义var a=10; */// console.log(a);//event.js:199 Uncaught ReferenceError: a is not defined//变量的声明提升--在执行过程中,会先声明var a;var b;/* console.log(b);//undefined--var a=10;var b=12; *///函数提升,变量提升//执行顺序:声明var a;声明函数ƒ a(){console.log(a);}-->调用a()-->console.log(a);-->a=10;a();console.log(a);////ƒ a(){console.log(a);}var a=10;function a(){console.log(a);//ƒ a(){console.log(a);}}
闭包以及实现累机器和缓存
闭包使用

//闭包累加器/* function count(){var num=0;return function(){return num++;}}var adder=count();console.log(adder());//0console.log(adder());//1console.log(adder());//2//释放内存空间,用完了就释放adder=null; */
原型
//原型function User(name,age){this.name=name;this.age=age;}console.log(User.prototype);User.prototype.eat=function(){console.log(this.name+'在吃饭');}User.prototype.gander='男';console.log(User.prototype);let user1=new User("嘎嘎",27);console.log(user1);let user2=new User("嘉尔",27);console.log(user2);
原型检测—instanceof

//原型检测//判断user1是否是Userconsole.log(user1 instanceof User);//true
类型检测—typeof
//类型检测console.log(typeof('abc'));//stringconsole.log(typeof(123));//numberconsole.log(typeof(user1));//objectconsole.log(typeof({}));//objectconsole.log(typeof(true));//booleanlet a=123;console.log(typeof(a)=='string');//falseconsole.log(typeof([]));//objectconsole.log(typeof(null));//objectconsole.log(typeof(undefined));//undefinedlet b=[];console.log(b instanceof Array);//true
正则表达式


















