目录
day one
1.1,JavaScrip—脚本语言
1.2,输出
1.3,应用举例
1.4,基础了解
1.5,数据类型
1.6,类型转换
1.7,运算符
1.8,流程控制语句
Day two
2.1,对象
2.2,函数 function
2.3,作用域:
2.4,函数方法call( )&apply( )&bind()
2.5,this
2.6,工厂&构造函数&原型:
day three
3.1,数组(Array,一种对象)
3.2,原生 js 操作数组方法:
3.3,Math对象
3.4,Date日期对象
3.5,正则表达式
3.6,字符串和正则
3.7,字符串方法
day four
4.1,DOM文档对象模型
4.2,事件:
4.3,DOM查询
4.4,DOM对象的其它属性和方法:
4.5,DOM增删改查
4.6,操作内联样式
4.7,其他样式相关的属性:
4.8,事件对象:DOM Event
day five
5.1,BOM
5.2,JSON
day six
6.1,栈&堆
6.2,变量&函数提升&同名函数
6.3,回调函数
6.4,作用域与作用域链
6.5,闭包closure
6.6,箭头函数
6.7,ES6部分
day seven
7.1,javascript编程题
本文内容参考视频:https://www.bilibili.com/video/BV1YW411T7GX?p=124
本教程资料、课件下载地址:https://shimo.im/docs/8RpVGykkWrqvxDyv/read
回调函数 ES6: git命令
特点:解释型语言,面向对象,动态,轻量级脚本语言
类型:使用{ }分组,一个{}中的语句一个代码块,共同执行,外部可见
执行:从上到下执行逐步执行,一个{}全执行/不执行
位置:标签中
页面弹出警告框:window.alert("哥,你真帅啊!!");
页面中输内容:document.write("
""+j+"""); //空格+换行+很多空格 innerHTML
控制台输出内容:console.log("你猜我在哪出来呢?");
接收用户输入: var score = prompt("请输入小明的期末成绩(0-100):");
验证输入:if isNaN(x) { alert("不是数字"); }
对事件的反应:
改变 HTML 样式:x=document.getElementById("demo"); x.style.color="#ff0000";
改变 HTML 内容:x=document.getElementById("demo"); x.innerHTML="Hello JavaScript";
直接写入文档输出:
xxx
进制: a = 0x/0/0b10; 16/8/2
字面量:恒定的值,注释// /* */,字符“ ” ‘ ’
变量声明:var a,b,c; var a=100,b=32,d;
转义字符:\\ '\' \n 换行 \t 制表符
调用方法:xxx.yyy( ); var a = 123; a=a.toString( );
JS编码规则:严格区分大小写,每一条语句以;结尾,忽略多个空格和换行
标识符定义:可以自主命名,如变量名,函数名,属性名等
标识符组成:字母、数字、_、$组成,不以数字开头,不是关键字和保留字,首小其大,xxxYyyZzz
var foo = "10"+3-"1";console.log(foo); //102
基本数据类型(栈) | ||
---|---|---|
字符串 | String | 单引号,双引号都可,“ d ‘a’ c” var a="aaa"; var b=a[0]; " \" \" " |
数值 | Number | 包括整数和浮点数(小数)var y=123e5; // 12300000 最大 Number.MAX_VALUE,任何值和NaN运算都为空 |
布尔值 | Boolean | true---数值非0/对象 false--0/undefined/null/NAN/空 |
空值 | Null | 定义并赋值,值为null,表示一个为空的对象 ,垃圾回收设a=null |
未定义 | Undefined | 定义但未赋值 NaN 保留字(表明数据类型不是数字) |
对象(引用)类型(堆) | ||
对象 | Object | 引用数据类型 var a={xxx:xxx,xxx:xxx} |
函数 | Function | 一种特别的对象(可执行) var ca=["S","V","C"] |
数组 | Array | 一种特别的对象,下标从0开始 var ca=new Array("S","V"); ca[2]="C" |
判断 |
||
typeof | 检查变量类型 结果:null与array都显示object |
console.log ( typeof [1,2,3]); //Object console.log ( typeof null); //Object |
instanceof | 检查对象是否是类的实例 即判断对象的具体类型 |
console.log (b1 instanceof Object); |
=== | 数据对象和类型都等 | console.log (typeof a===‘ undefined' ); |
in | 检测属性是否属于该对象 | console.log(“属性名”in 对象); |
isNAN | 检查是否是数字 |
隐式转换:var a ='a' b=!!a //true c=false d='a'+c //afalse d='2' e=6/d //3
其它—》字符串:a=a.toString( ); // null/undefined不可 a.toString(2); //转换成二进制
其它—》字符串:a=String(a);//null/undefined直接原样输出
其它—》布尔:b=Boolean(a); //0/NaN/null/undefine/空串---》false
其它—》数字:a=Number(a); // true/false/null/空串/undefined/非数字字符串-》 1/0/0/0/NaN/NaN
字符串—》数值: parseInt (a,16)/parseFloat(a); 转化成16进制整形,16/10需表明最好不省略
分类 | 举例 | 特点 |
---|---|---|
逻辑运算符 | && 与 || 或 ! 非 | 同真/假即真/假,有假/真即假/真,取反,化boolean看 |
关系运算符 | > >= < <= | 一般化化数值比较,任何值和NaN做任何比较都是false 字符串间逐位比较按Unicode编码,返回boolean值 |
相等运算符 | == != === !== | 转换为同类型比较,后二不转换,返回boolean值 |
if语句 | 条件分支语句 | while循环 |
---|---|---|
* if(条件表达式) * { * 语句... * }else if { * 语句2... * }else{ * 语句3... * } |
* switch(条件表达式){ * case 表达式: * 语句... * break; * case 表达式: * 语句... * break; * default: * 语句... * break; * } |
* while(条件表达式){
* do{ |
for循环 | break/continue | |
* for(①初始化表达式;②条件表达式;④更新表达式){ * * break:终止循环 * continue:跳出本次循环
|
outer: for(var i=0 ; i<5 ; i++){ console.log("@外层循环"+i) for(var j=0 ; j<5; j++){ break outer; console.log("内层循环:"+j); } } //输出:@外层循环 |
分类:内建对象(ES标准)/宿主对象(浏览器提供)/自定义对象
创建:new调用函数为构造函数(首字母大写),var obj = new Object( ); var obj={ }
添加:对象.属性名=属性值 obj2.name = "孙悟空"/obj1 obj2.ca=fun( ){ }; ca为函数名
对象["属性名"]=属性值 //属性名含特殊字符/不确定 obj1['co-dj]=a;
删除:delete 对象.属性名; delete obj.name;
读取:对象.属性名 console.log(obj.name/obj.ca()); //obj.ca--调用对象的属性,返回一个函数字符串
循环:for(var i in obj){ } '属性名‘ in 对象 //检查对象中是否含有该属性
对象字面量: var obj1={name:"a",id:1,test:{name:"b"},a:function( ){ }}; //a为函数名
创建:function 函数名([形参1,形参2...]){ 语句... } function fun2( ){ } //可先调用后写
var 函数名 = function([形参1,形参2...]){ 语句... } ; //同变量,不可先调用后写,有;
调用:函数名(实参1,实参2...); 任意类型,自检查,多不管,少为undefined
用例:function f3 (a,b){console.log(“a=”+a);} var a =f3(1,3);
返回值:任意类型/对象/函数,不写return或a默认返回undefined
//立即执行函数:函数定义完,立即被调用,往往只会执行一次
(function(a,b){console.log("a +b= "+a);;})(1,2);
//枚举,obj为定义好含很多内容的对象
for(var n in obj){ //4个属性执行4次
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
} //每次执行时,会将对象中的一个属性的名字赋值给变量
1.全局作用域 全局对象window调用,任意位置都可访问,不可调用函数变量
2.函数作用域 函数调用时创建,彼此独立,可访问全局变量,报错ReferenceError
定义形参就相当于在函数作用域中声明了变量
//使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
var a=10;
function fun3(){ console.log(a); var a = 35;} //若无,则a=10;
fun3(); //输出:a=undefined
//在函数中,不适用var声明的变量都会成为全局变量
var c = 33;
function fun5(){ console.log("c = "+c); c = 10; d = 100;}
fun5(); //输出:c=33;
console.log("d = "+d); //输出:d=100
让一个函数成为指定对象的方法进行调用 详解 bind返回的是一个函数后有()
function fun(a,b) {
alert(this.name); //使用call和apply调用时,this是指定的那个对象
console.log("a = "+a);
console.log("b = "+b);
}
//fun.apply()=fun.call()=fun();
var obj1 = { name: "obj1" };
var obj2 = { name: "obj2" };
fun.call(obj1); //输出:"obj1"
fun.call(obj2); //输出:"obj2"
//第一个参数的对象,为函数执行时的this
fun.call(obj,2,3); //call()方法可以将实参在对象之后依次传递
fun.apply(obj,[2,3]); //apply()方法需要将实参封装到一个数组中统一传递
定义:解析器/浏览器调用函数向内部传递进的一个隐含参数
指向:以函数的形式调用时,this永远都是window
以方法的形式调用时,this就是调用方法的那个对象
以构造函数的形式调用时,this就是新创建的那个对象
使用call和apply调用时,this是指定的那个对象
在事件的响应函数中,响应函数是给谁绑定的this就是谁
function fun(){
console.log(this.name);
}
var name = "全局的name属性";
var obj = {
name:"孙悟空",
sayName:fun,
id:1
};
fun(); //输出:"全局的name属性"
obj.sayName(); //输出:"孙悟空"
console.log(obj.id); //输出:"1"
function createDog(name , age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function(){
alert("汪汪~~");
};
return obj;
}
var obj2 = createPerson("猪八戒",28,"男");
var obj3 = createPerson("白骨精",16,"女");
var obj4 = createPerson("蜘蛛精",18,"女");
使用构造函数创建对象:function Do ,首字母大写,调用多new var a =new f3(1,3); 类,实例
每一个对象都添加了sayName方法,浪费,若在全局作用域中定义,不安全
function Person(name , age , gender){//Person 类
this.name = name; //构造函数的执行流程:
this.age = age; //1.立刻创建一个新的对象
this.gender = gender; //2.将新建的对象设置为函数中this
this.sayName = function(){ //2.在构造函数中可以使用this来引用新建的对象
alert(this.name); //3.逐行执行函数中的代码
}; //4.将新建的对象作为返回值返回
}
function Dog(){ }; //Dog 类
var dog=new Dog; //dog 实例
var per = new Person("孙悟空",18,"男"); //per per2 实例
var per2 = new Person("玉兔精",16,"女");
console.log(per instanceof Person); //检查对象是否是类的实例
console.log(dog instanceof Person); //输出:true false
//显示原型prototype,隐式原型__prto__ ,对象隐式原型的值==对应构造函数显示原型的值
//原型对象有一个constructor属性,它指向函数对象 即 fun.prototype.constructor===fun ---true
function MyClass(){
}
MyClass.prototype.a = 123; //向MyClass的原型中添加属性a
MyClass.prototype.sayHello = function(){
alert("hello"); //向MyClass的原型中添加一个方法
};
var mc = new MyClass(); //_ _两横,通过proto访问隐含属性
console.log(mc2.__proto__ == MyClass.prototype); //输出:true
console.log(mc2.a); //输出:"123"
mc.a = "我是mc中的a"; //查找属性,先自己,在公共
console.log(mc2.a); //输出:"我是mc中的a"
//向原型中添加sayName方法
Person.prototype.sayName = function(){
alert("Hello大家好,我是:"+this.name);
};
检查对象(原型)是否含有这个属性:console.log(“属性名”in 对象); 返回true/false
检查对象自身中是否含有该属性:console.log(mc.hasOwnProperty("age"));
原型即对象 也有原型,祖先Object: console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
创建:var arr = new Array(10,20,30); //一个数字则表示数组长度,对象任意类型
var arr = ["hello",1,true,null,undefined]; //使用字面量创建数组
添加:数组[索引] = 值 arr[0] = 10; //索引从0开始
读取:数组[索引] console.log(arr1[3]==arr2[3]);
求长:console.log(arr.length) 值为最大索引+1 arr.length=7 //修改长度为6,多则删
修改:arr.length = 10; 多空出,少删除 arr[arr.length] = 70;
遍历:for(var i ; i<数组.length;i++){ } 数组.forEach(function(value,index,obj){ });
unshift():数组开头添加元素,并返回添加后的个数 arr.unshift("12","22");
push():数组末尾添加元素,并返回添加后的数组个数
pop():删除数组最后一个元素,并返回删除的元素
shift();删除数组的第一个元素,并返回删除的元素
slice(a,b):提取a~b,不包括b,复制到新数组中,b可省,a=-1表最后一个元素,a=arr.slice(0); //复制arr
splice():删除原数组从a开始的b个元素,在插入c arr.splice(3,1,"牛魔王","红孩儿");
concat():连接多个数组,返回新数组 var result = arr.concat(arr2,arr3,"王"); //连接arr,arr2,arr3,王
join():将数组转换为一个字符串并返回新,若有a则默认作为连接符 arr=[1,2]; a= arr.join("@"); 1@2
reverse():反转原数组
sort():按Unicode编码排序原数组 arr.sort(function(a,b){ return a - b/b - a; }); //升序/降序排列
indexOf(): 查找数组中是否有某项,有的话返回该项的所引,没有话返回-1;
toString():把数组转成以逗号分隔的字符串
forEach(function(value,index,obj){ },value):循环(元素/索引/数组)
filter(function(currentValue,index,arr), thisValue):1必须,其它可选,创建新数组,为符号函数要求的旧数组构成
Math.floor(): 向下取整
Math.ceil():向上取整
Math.random():取0-1之间的随机小数 Math.round(Math.random()*(y-x)+x); //(x,y)之间
Math.round():四舍五入取整
Math.abs():取绝对值
Math.pow(x,y): x的y次幂
Math.sqrt():开平方
Math.max():取最大值
Math.min():取最小值
Math.PI:常量,圆周率
new Date() | 创建一个日期对象 |
Date() | 将日期转换成字符串 String(new Date()) |
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 //设置用set |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数。 |
含义:定义字符串的规则,检查字符串是否符合规则,是对象
创建:使用字面量:var 变量 = /正则表达式/匹配模式 var reg=a/gi; 方便 i 忽略大小写
使用构造函数:var 变量 = new RegExp("正则表达式","匹配模式"); 灵活 g 全局匹配模式
检查:var reg = new RegExp("a","g"); var str = "xasd"; console.log(reg.test(str));
//输出:true,检查str是否含a,严格区分大小写
举例:var phoneReg = /^1[3-9][0-9]{9}$/; //检查手机号,1开头,第2个3-9,9个0-9结尾,若无$则131111111118908对
reg = /\bchild\b/; //查找含child独立的单词,前后为空 即 a child live
var str=" ss "; str = str.replace(/\s/g , ""); //ss 去除所有空格
str = str.replace(/^\s*|\s*$/g,""); //去除开头和结尾的空格,无g则不全局,可能至去除前面的
量词 | |||||
---|---|---|---|---|---|
{n} 正好出现n次 |
/a{2}/ | aa | ^ 表示开头 | /^a/ | a... |
/ab{2}/ | abb | $ 表示结尾 | /a$/ | ...a | |
/(ab){2}/ | abab | 混合 | /^a$/ | a | |
{m,n} 出现m-n次 | /a{1,3}/ | a~aaa | 任意 | /a|b|c/=/[ab] | a或b或c |
{m,} m次以上 | /a{1,}/ | a~a... | 全选 | /[a-zA-Z]/ | 任意字母 |
+ 至少一个,同{1,} | /a+b/ | ab~a...b | [a-z] | 任意小写字母 | |
* 0个或多个,同{0,} | /a*b/ | b~a...b | [0-9] | 任意数字 | |
? 0个或1个,同{0,1} | /a?b/ | b/ab | 除了 | [^0-9 ] | 不含数字 |
^(0|[1-9][0-9]*)$ | 只能输入零 | +非零开头数字 | \num | /[a-z]\1/ | 出现重复字母 |
转义字符 | |||||
\w 任意字母、数字、_ | reg = /\w/; | = / [A-z0-9_] / | \s | 空格 | reg = /\s/; |
\W除了字母、数字、_ | reg = /\W/; | =/ [^A-z0-9_] / | \S | 除了空格 | reg = /\S/; |
\d 任意的数字 [0-9] | reg = /\d/; | =/ [0-9] / | \b | 单词边界 | reg = /\b/; |
\D 除了数字 [0-9] | reg = /\D/; | = / [^0-9] / | \B | 非单词边界 | reg = /\ |
replace() | 将字符串中指定内容替换为新的内容,默认只第一个 result = str.replace(/[a-z]/gi , "@_@"); |
match() | 会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果 |
split() | 将一个字符串拆分为一个数组 var str = "1a2cd3"; var result = str.split(/[A-z]/); //输出:1,2, ,3 |
search() | 搜索字符串中是否含有指定内容,有返回索引,无返回-1,默认只第一个 result = str.search(/a[bef]c/); |
slice() | 将符合条件的内容从字符串提取出来通过数组返回,默认只第一个 result=str.match(/[a-z]/); |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分 |
toLower/UpperCase() | 把字符串转换为小/大写 |
trim() | 移除字符串首尾空白 |
last/ IndexOf() | 返回字符串中检索指定字符最后/早一次出现的位置 |
substr() | 从起始索引号提取字符串中指定数目的字符 |
concat() | 连接两个或多个字符串,返回连接后的字符串 |
charAt() | 根据索引获取指定的字符 |
charCodeAt() | 根据索引获取指定的字符编码 |
定义: Document Object Model (网页 节点 关系)
查询:W3Cschool离线手册--》JS--》JavaScript 对象---》HTML对象--》找对应a/...对象属性操作
文档节点(document):代表网页,所有节点都是它的子节点,直接使用
元素节点(element):
document.getElementById/getElementsByTagName/getElementsByName(“ ”);
通过id属性/标签名/name获取一个/一组/一组元素节点对象
元素节点通过innerHTML获取和设置标签内部的html代码,自结束标签不行,元素.属性名
文本节点(text):
获取元素节点的子节点:通过具体的元素节点调用
元素节点.getElementsByTagName(“ ”); //返回当前节点的指定标签名后代节点
元素节点.childNodes/firstChild/lastChild //返回当前节点的所有/第一/最后子节点(包括文本节点--标签间的空白)
元素节点.children/firstElementChild //返回当前节点的所有/第一/最后子元素
文本节点通过nodeValue属性获取和设置文本节点的内容 //alert(bj.firstChild.nodeValue);
属性节点(attribute):元素节点.getAttributeNode(“属性名”); //一般不使用
定义:用户和浏览器之间的交互行为,如:点击按钮,移动鼠标,关闭窗口等
方法一: //结构和行为耦合,不推荐
方法二:var btn = document.getElementById("btn");btn.onclick = function(){ alert("你还点~~~"); }; //推荐
//原因:代码由上而下执行,页面未加载,即DOM对象未加载,故无法获取到DOM对象
//解决:为window绑定一个onload事件