1.搭建JS开发环境;
(1)在控制后台输出:console.log()。
(2)在HTML页面输出:
1).html页面元素事件中输出,如οnclick="";
2) .通过,并且script可存在html 任意标签位置。
3).写到外部js文件,通过引入;
script的属性;src,type,defer(设置延迟),async(异步加载页面内容)。,defer用户外链script标签中,在其他js和dom执行完之后,再执行该script外链文件。多个defer时,会依次加载。 |
2.代码块;指里面包含的js代码为一块代码块,js是按代码块顺序执行。
3.浏览器内核;内容排版引擎(html和css)和脚本解释引擎(js)。
4.Error;指程序的代码错误,导致程序中断。
(1)错误处理:指的是程序代码错误,仍然不会导致程序中断的机制。
如:try{
//可能出错的正常代码
}
catch(err){
//出错后的处理代码包括用户提示,保存进度,日志记录
}
finaly{
//一段无论如何都会执行的代码
};
(2)错误类型:SyntaxError,RangeError,ReferenceError,TypeError,URLError, EvalError。
5. 字符集:js是用unicode字符集编写的,几乎支持地球上所以语言。
6.区分大小写:js严格区分大小写。
7.注释://表示对内容的单行注释,/**/是段注释。
8.转义字符:反斜杠' \ '。\n(换行符),\f(换页符),\\(反斜杠),\'(单引号),\r(回车符),\"(双引号)。
9.with语句:但是现在不推荐使用。
with(document.form[0]){
name.value="";
email.value="";
}
//等价于以下语句
var f=document.form[0];
f.name.value="";
f.email.value="";
10.debuggger:开发模式下,打断点调试。
(二)JS基本语法;
1.基本语法;
(1)字符集:JS是由Unicode字符集编写的,且严格区分大小写,但html不区分大小写。
(2)注释://和/**/,转义字符 \仅仅对特殊字符有转义功能,对正常字符没有效果 ,如\t(制表符),\",\',\\(一个\)。
2.变量;
(1)定义:通过var/let关键字声明(如var/let a),或者不需要关键字的全局变量声明(a),变量是由字母,数组,'_'和'$'组成,数字不能作为首位出现,且js关键字不能作为变量名。常用的命名方法有:下划线命名法,驼峰命名法,大驼峰命名法,匈牙利命名法...。
(2)特征:var声明多个变量,号隔开,不用var声明视为全局变量,调用为声明的变量为语 法错误,调用声明未赋值的变量为undefined,var的声明不能使用delete 删除该变量,if(var i)和while(var i)是语法错误的,for(var i(in))是可以的,js会声明提前。
3.数据的基本类型;
(1)包括:undefined,null,number,string,boolean六种基本类型,typeof只能区分基本数据类型和函数,但是不能准确区分对象和数组。其 中typeof a,如果a未声明,仍然返回undefined,不报语法错误。
问题:怎么区分对象和数组,或者区分对象和数组的几种方法? 1.构造函数。2.父原型对象。3..class属性。4.Array.isArray(obj)。5.obj.constrctor。注意:.constructor可以检测大部分数据类型,但是对象null和undefined会抛出异常错误,这时可以把值先转为布尔值,true表示存在然后在调用.constructor。typeof的结果为字符串"类型"。.constructor的结果为如String。 (15)可将数值转换为对象。 |
(2)Number数值类型:不在区分整数和浮动型,所有数值都是浮动型。整数32位, 浮动64位一般。
1).toString(2~36进制参数):可以吧数值转换为对应进制的字符串。注意: a/(25).toString(),25数字必须加括号,否则语法错误。
2).浮动数溢出:即二进制的浮点数不能正确处理十进制小数,如0.1+0.2不等于0.3,但是可以转换为(1+3)/10;
3 ) .特殊数值NaN:NaN==="number"且NaN !==NaN,isNaN(num)用于判断数字与NaN;isNaN("A")==true,isNaN("15")==false;即纯数字形式的字符串是数值。
4).isFinite(num):判断num是否是NaN,无穷大的数值,Infinity(正无穷大),-Infinity(负无穷大)。
(3)字符串String类型:有.length,有下标,可遍历,应在一行内显示不允许换行,换行用换行符\n,+在字符串中有拼接的作用。
(4)布尔值boolean类型:在js中undefined,null,"",0,NaN和false这6个 值转换为逻辑值时时false,被称为假值,其他任何类型的数据转换为逻辑值都是 true。如Boolean(NaN)==false; 其中!a 等价于 a==null; b=b?b:"OK",表 示如果b为null,则b="ok",否则b=b;
(5)Underfined类型:其唯一值underfined,null==undefined,都是假值所有成立。但类型不同所有null===undefined是不成立的。a==undefined,在已声明 a下时判断a是否赋值,未声明a下是语法错误。函数在没返回值下,调用输出 undefined。
注意:显式类型转换(即强制转换):Boolean(),Number(),String(),Object()。
4.严格模式;"use strict";
(1)在全局script下顶端或在函数下顶端(前可有注释)声明,否则无效。
(2)严格模式的执行:
1.不允许全局变量,否则语法错误。
2.静默失败升级为错误。
3.this不在默认指向全局。如果function f() {return !this;} //返回false,因为在非严格模式下 this指向全局,!this表示不是指向全局,所有是错误的。 但是unction f(){"use strict"; return !this;} // 返回true,因为在严格模式下,this指向undefined,所有!this表示不指向全局指向undefined。
4.禁止调用argunments,callee,caller,禁止递归函数,否 则语法错误。
5.函数参数重名则报错,对象重名也报错,对对象的四大只读 属性赋值修改也会报错。
6.禁止在非函数的代码块内声明函数,如在条件和循环语句中 声明函数是语法错误。
(三)运算符;
1.算术运算符:+,-,*,/,%,-(取反),++,--;
(1)以上算术运算符的特殊规则:
1).任意数(包括0与无穷)与NaN运算结果都是NaN。
2).正负无穷之和为NaN,两负无穷之差为NaN。
3).正负无穷与任意非0非NaN之乘积为无穷, 否则为NaN。
4).正负无穷与无穷相除为NaN,任意数与0, -0相除都正负无穷大。
5).无穷模任意数(包括0和无穷)结果都是NaN, 任意非无穷数模无穷数,结果为模前面那个非无穷数,0模任意数结果为0.
6 ).++,--只能作用于变量,数组元素,对象属性, 不能作用于具体的数值,如4++为错误。
2.逻辑运算符;&&,||,!。
(1)六个假值:null,undefined,NaN,"",0,false。其余类型都是true。
(2)逻辑与(&&):式1 && 式2;其中式1,式2结果为false/ture,但是这个逻辑与&&,结果不一定是false/true。如果式1或式2中包含 null/NaN/undefined,则返回相应的null,NaN,undefined。无穷大Infinity为true。&&优先级高于||。
(3)逻辑或(||):式1 || 式2;与逻辑与(&&)用法一样。
(4)逻辑非(!):! 式1;结果一定是false/true。 !a <=> a==null是true。
注意:if(式1 &&(||) 式2){}时;先要判断是否会短路逻辑造成式2不能被执行,然后在判断判断整个式1 && 式2的false/true而确定是否执行if语句。
3.关系运算符;<,>,<=,>=,==,===,!=,!==。
(1)规则:
1.如果运算数都是数字,或一个数字一个纯数字形式的字符串,则转换为数字进行比较运算大小。
2.如果都是字符串,或一个布尔一个字符串,则转换为字符串比较 unicode码大小。
3.如果一个是数字,另一个是字符串,则用parseInt()转换为数字 比较(开头不是数字的字符串会被转换为NaN)。
4.引用对象的值来说,==与===操作的结果都是一样的,即使值一样,但是地址不一样,也都是false。如var a={},b={};c=a;则a与 b值相等地址不相等,结果即不全等又不相等,而c与a地址和值都相等,所有即全等又相等。
注意:(a in obj)中in运算符可检测属性a是否是对象obj或由其继承来的成员。
4.赋值运算符;=,+=,-+,*=,/=,%=,&=,^=,|=。
(1)连续赋值:var a=b=c=d=f=10;此类1=100赋值为false。
(2)优先级:(a=6&&(b=function(){return a;})()); 返回undefined,因为=号比&&和()运算低,所有先执行b,结果b中a没有赋值。
5.对象操作运算符;new,delete,[]和.,(),in。
(1)new:创建一个新对象。
(2)delete:删除指定的对象的属性,数组的元素,或变量(var声明的变量不 能删除)。结果返回true/false。如果删除不存在的时返回true,且其只删除值类型的数据。不是清空值(null),而是把其值变为了undefined。
(3)[]和'.':用于访问对象或数组。[]可以将里面的纯数字字符串转换为数字,且 可以通过变量或者字符串表达式来间接传递特定值。如var b="x",var a={x:1};a[b]返回1,而a.b返回undefined。
(4)in运算符:判断一个元素是否是一个对象(key名)或一个数组的元素。
6.其他运算符;三目运算符(?:) ,逗号(,) ,void运算符,eval()运算符,typeof运算符。
(1)注意:逗号运算符优先级最低,且a=(b=1,c=2);结果a=2。
(2)void:出现在任意类型运算符之前,总是使得结果返回undefined。如void1或函数void(a,a++),结果都是undefined。
(3)eval(表达式):计算并返回表达式的结果。
(4)typeof a:判断a的类型,但是不能区分array和object。注意 typeof undefined返回undefined,typeof null返回object。
(四)程序逻辑结构;
1.空语句:没有任何代码只有一个';'号的语句不会执行和报错,如; 或 for();
2.逻辑结构:
(1)顺序执行;
(2)选择执行;
1).if(){};
2).if(){}else{};
3).if()else if(){}...else if()else{};
4).switch(){...case 值...(default...};
5).选择的嵌套;
注意:选择逻辑中的条件语句即()里的语句,不能var 声明变量,且特别注意如果是短路逻辑判断表达式2是否已声明,因为短路逻辑可能让表达式2不能执行,且注意运算符的优先顺序。
(3)循环执行;
1).while(){}; 循环条件为true不变时为死循环。
2).do{}while();
3).for(;;){};仅遍历原生属性。
4).for(... in ...){};结果是依次获得下标而非值,可以遍历原生(自有)属性和继承属性,以及额外属 性(即添加进去的属性);
5).for(... of ...){};
注意:循环结构是最浪费资源的;
3.结构跳转: 1).break; 中断当前层的循环。
2).continue; 跳过当前层的当次循环,进入下一次循环。
(五)数组;
1.创建数组: 1).var arr=[];
2).var arr=new Array();
2.数组的length:
1).JS中可以不按照下标顺序添加新元素,且直接未赋值的下标的值预定义为undefined。如果获取下标对应的值不存在也是返回 undefined。且下标值必须>=0 && <2^32-1。如果下标值太大,或为负数,浮点数,布尔值,对象和其他值,JS会自动转换为字符串作为关联数组的下标。
2).对arr.length=5;如果arr原来的长度大于5,则截断arr使得其长度为5,超出部分会丢失。如果小于5,则会尾部添加预定义undefined值,使得其长度为5.
3).in运算符,如("a" in arr),用于判断"a"是否是arr里面的值,返回布尔值。
3.二维数组:JS不支持二维数组,但是可以通过其他样式构造操作,如循环的嵌套。
4.操作数组的API:
1).遍历数组;for(){}或for(..in..){}; Array.isArray(arr),判断arr是否是数组。
2).增删数组元素;
(1) delete arr[i]; 删除元素的值,而不是元素,不改变其数组的长 度。
(2) arr.push(e1,e2...)/unshift(e1,e2...);在数组的尾部/头部添加元素e1,e2...,返回新数组的长度。
(3) arr.pop()/shift();删除数组的尾部/头部的最后一个/第一个元素,返回删除后的元素。
(4) arr.concat(arr1,arr2...);向数组arr尾部添加新数组arr1,arr2...的元素,返回新数组。
var a=[1,2,3];
a.concat(4,5) //返回结果[1,2,3,4,5]
a.concat([4,5]) //返回结果[1,2,3,4,5]
a.concat([4,5],[6,7]) //返回[1,2,3,4,5,6,7]
a.concat(4,[5,[6,7]]) //返回[1,2,3,4,5,[6,7]]
3).增删改数组的元素;
(1) arr.slice(start,end);截取并返回arr的子数组。
(2) arr.splice(start,count,e1,e2,...);增删改数组返回新数组, count表示删除的个数,如果为0或为负表示都不删除。
4).数组排序;
(1) arr.sort();如果sort()没有参数,表示按照unicode码升序排序,且自动把数组元素转换为字符串/数字。Undefined默认排到尾部。 如果数组元素全为数值且参数是匿名函数function (a,b){//return a-b/b-a};表示如果返回a-b为升序,b-a为降序。
5).数组与字符串的转换;
(1) arr.toString();表示把数组按,号隔开元素转换为字符串。可以把 二维数组的每个元素都隔开转为字符串。
[1,2].toString() //返回'1,2'
['1','2'].toString() //返回'1,2'
[1,[2,3]].toString() //返回'1,2,3'
(2) arr.join("分隔符");表示把数组的元素按"分隔符"转换为字符串,不写默认将数组元素按照','号转换为字符串。
var a=[1,2,3];
a.join() //返回"1,2,3"
a.join("") //返回"123"
a.join(" ") //返回 "1 2 3"
6).定位与倒序;
(1) var i=arr.indexOf("字符",fromi):从头向尾开始查询匹配,直到找到第一个匹配或查找完所有元素,没有返回-1;
(2) var i=arr.lastIndex("字符",fromi):从尾向头开始查询匹配,直到找到第一个匹配或查找完所有元素,没有返回-1;
(3) arr.reverse();将原数组倒序排列,返回原数组。
7).迭代;
(1) var bool=arr.every/some(function(elem,i,arr){return});表示判断数组中是否所有元素都符和条件/是否包含符合条件的元素,返回true/false。
(2) arr.forEach/map(function(elem,i,arr){return});对数组中每个元素执行相同的操作并返回原数组/新数组,forEach会修改原数组,map不会修改原数组。
(3) arr.filter(function(elem,i,arr){return});从原数组中选取符号条件的元素组成新数组。
(4) arr.reduce(function(prev,elem,i,arr){});数组中每个元素的累加和,返回累加和值。
(六)函数;
1.定义:保存一段封装的代码的对象。
2.创建方法:
1).function 函数名(){};
2).var 函数名=function(){};
3).var 函数名=new function("参数","函数体");
3.重载:在js中,相同函数名,传入不同参数,执行不同的操作。默认js不支持重载,但是可以用函数自带的接收参数的类数组argunments。
1.String有关的API;
(1)String VS数组: 相同点;1.下标。2.length。3.for遍历。4.slice()截取。
不同点;类型不同,所有API不通用。
(2)大小写的相互转换:str.toUpperCase();返回新字符串。
str.toLowerCase();返回新字符串。
(3)字符串与unicode的转换:var unicode=str.charCodeAt(字符串下标=0);
var str=String.fromCharCode(unicode);
(4)截取子字符串:var str1=str.slice(start,end);返回新字符串。
var str1=str.substring(start,end);返回新字符串。
var str1=str.substr(start,n);返回新字符串。
(5)获取指定位置i的字符:var str1=str[i];
var str1=charAt(i);
(6)获取关键字符的位置:var i=str.indexOf("关键字符",fromi=0);
var i=str.lastIndex("关键字符");
(7)通过正则获取敏感词位置:var i=str.search(/正则/);
(8) 通过正则获取敏感词:var str1=str.match(/正则/ig);ig表示不区分大小写,全部敏感词获取。
(9)替换(删除)字符串的敏感词:var str1=str.replace(/正则/ig,"新内容");
var str1=str.replace(/正则/ig,function(kw){return kw=?});
(10)切割字符串成数组:var arr=str.split("自定义切割符");
var arr=str.split(/正则表达式/);
(11)去掉字符串的首尾空格:var str1=str.trim();
2.正则表达式;规定字符串中字符出现规律的表达式。一般API对其执行一次就返回。参考:https://mp.csdn.net/postedit/83036838。
(1)作用: 1.验证字符串格式,如邮箱,密码等。
2.查询字符串的敏感词。
(2)预定义字符集:\d => [0-9];
\w => [a-Za-z0-9_];
\s => 一切空字符,如空格,Tab键,换行....;
点‘.’ => 通配符;
(3)量词:定义字符集出现次数。{n.m},{n,},{n}, * , + , ? 。
(4)其他: 1. 分组()与选择 |;
2. 空字符首(^\s+),空字符尾(\s+$)及(\b单词\b);
3.RegExp;保存一条正则表达式,并提供操作验证和查找正则表达式的API对象。
(1)创建方法:1. var reg=/正则/ig;
2. var reg=new RegExp("正则","ig");
(2)应用:1. 验证格式;var bool=reg.text(str); 必须^和$。
2. 查找敏感词及位置;var arr=reg.exec(str); arr=[0:敏感词,index:位置],但是只能找到一个就返回,找不到返回null。
4.Math;保存一个数学计量的常量,并提供操作计算的API的对象。不需要创建。
(1)API:
Math.ceil(num)——取上整值;
Math.floor(num)——取下整值;VS parseInt(num);
Math.round(num)——四舍五入;VS num.tofixed(d);
Math.pow(底数,冥)——乘方;
Math.sqrt(num)——开方;
Math.max/min((...arr)/参数1,参数2,...)——最大、最小值;
Math.random()——0-1之间的随机数;
Math.abs(num)——绝对值;
Math.PI/E——π和e;
Math.exp(num)——e的num次幂;
Math.sin/log/cos(num)——三角函数;
5.Date; 保存一个日期值,并提供操作日期值的API的对象。并修改原日期值。
(1)创建方法:
1. var date=new Date();获取当前计算机的时间。
2. var date=new Date("yyyy/mm/dd hh:mm:ss");
3. var date=new Date(ms); 毫秒转日期。
var ms=date.getTime(); date转毫秒数。
4. var date1=new Date(date2); 复制日期副本。
(2)API:1. 八个单位;FullYear Month Date Day Hours Minutes Seconds/Milliseconds 。
2. 一对get/set函数;每个单位一对函数,除了Day没有set函数外,如date.getFullYear / getMonth /getDate / getDay / getHours / getSeconds / getMilliseconds()。
(3)日期的计算: 1. 两个日期直接相减,结果为毫秒数。
2. get获取当前日期值,在用set修改原日期值,返回原date。
(4)日期格式化(简化): to(GMT/Locale(Date/Time))String;
注意:js中的转义符:\n(换行符),\',\",\\。
6.Error;保存错误的对象。
(1)错误处理:即即使程序出错,也不会中断退出的机制。
(2)操作:try{//可能出错的正常代码}catch(err){//出错后执行的代码,提示用户,保存进度,记录日志/或throw new Error("错误信息提示")}。
(3)六种常见错误类型:
1. SyntaxError——语法错误;
2. ReferenceError——引用错误,即需要的变量没有找到;
3. TypeError——类型错误,即错误调用函数或对象的API;
4. RangeError——范围错误,即参数的范围错误;
5. URLError——URL格式错误;
6. EvalError——eval()错误,一般很少见;
7.Function;保存一段封装的代码的对象。
(1)声明创建的三种方式:
1. function 函数名(参数列表){//return 结果};
2. var 函数名=function(){}; 避免1那样的声明提前。
3. var 函数名=new Function("参数n","函数体");
(2)匿名函数:即不指定函数名,用后立即释放的函数。包括;
1. 回调;一个函数被另一个函数调用。如sort(),replace();
2. 自调;函数被自己调用。(function(){})();
(3)垃圾回收: 主动和自动;
(4)作用域与作用域链:变量的可用范围是作用域(分为全局,局部变量),由多级作用域逐级形成的链式结构为作用域链(控制着全局和布局变量)。以下是作用域与作用域链的形成。
(5)闭包:集合全局变量和局部变量的优点,既代码重用,又不会被篡改的机制。其是由于外层函数的活动对象AO无法释放形成。闭包可能占据更多的内存,但可以用完后立即赋值null释放内存。
1).步骤;1. 用外层函数包裹受保护的变量和函数,确定变量的最终值。
2. 将内层函数返回到外部,如return,或将内层函数赋值给全局变量,或将内层函数包裹在对象或数组中并返回这个对象或数组。
3. 调用外层函数,得到内层函数。
以下是闭包的形成:
(6) this;始终执行调用对象,或谁让调用(动了)函数,就指向谁(如window/button/子对象...),即谁调用,执行谁,如果没有就指向window,静态绑定this的方法;
1).将this作为参数传递进去,如;
2).在函数内将this存储给变量,如;function f(){var _this=this...return _this};
3).bind(thisobj,...);永久静态绑定一个指定的obj对象。使用new创建一个this指向实例对象。
(7)函数的调用方法;
1).方法/元素调用,函数作为一个对象的方法,用.调用如.onclick。
2).函数调用,用函数名()直接调用此时this相当于window的调用。
3).构造函数调用,用new构造函数的子对象,然后子对象调用构造函数方法。
4).apply/call(),强行调用函数。
(8) 优先级;
1).函数名和形参同名下,形参变量名优先级高于函数。
2).函数名/参数与作为传参的类数组arguments同名下,参数要优先级高于类数组高于函数。
3).局部变量(已赋值下)与形式参数同名下,赋值的局部变量优先级高,如果是局部变量没有赋值,形参的优先级高于局部变量。通常下应用把形参直接赋值给其函数内的局部变量。
(七)对象;
1.定义:描述一个现实中具体事物的属性和功能的程序。
2.面向对象:就是程序用对象结构来描述一个具体事物的属性和功能,便于大量数据的管理和维护。
3.三大特点:
1).封装:
⑴ 直接量:var obj={属性:值,...,方法(){},...};this.属性名表示对象自己访问自己的属性及方法都必须这样。
⑵ new创建空对象:var obj=new Object();创建空对象,obj.属性名/["属性名"]=值,依次向对象中添加属性及值。
⑶ 构造函数:构造函数,function类型名(){this.属性名=属性参数,...,this.方法名=function(){}};调用自 己的属性,用.属性名/方法名即可。
2).继承:父对象的成员,子对象无需创建API就可以直接调用。
1).原型对象;保存同一类型的所有子对象共有方法的父对象。添加:构造函数.prototype.共有方法=值/function(){};
2).自有属性及共有属性;仅当前对象所有的属性为自有属性,保存在原型对象中为所有子对象共有的属性为共有属性。二者都可 以通过子对象.属性名获得其属性值,但是自有属性的修改为子对象.属性名=值,共有属性的的修改为构造函数
的.prototype.共有属性=值;var bool=obj .hasOwnProperty("属性名"),用于判断是否包含指定的自有属性,true为自有属性,false为没有属性或是继承属性。
3).内置对象;内置对象是ES标准中,浏览器厂商已经实现的对象,包Number,String,Boolean(这三个为包装类型),Array, Math,Date,RegExp,Error,Function,Object,Global(Window)共11中内置对象,包装类型指专门封装一个原始类型的值并提供操作原始类型指的API的对 象,内置对象由构造函数和原型对象组成。
4).原型链;由多级父元素逐级继承形成的链式结构。控制着属性和方法的使用顺序,VS作用域链,保存和控制所有的变量的使用顺序。如下图:
5).实例方法与静态方法;
⑴ 修改一个对象的父对象:Object.setPrototypeOf(child,father);
⑵ 修改一类对象的父对象:构造函数.prototype=father;
⑶ 自定义继承:包括定义抽象父类型(父类型构造函数及父类型原型对象)和让子类型继承抽象父类型(子类型原型对象继承父类型原型对象,子类型构造函数借用父类型构造函数)。如下图;
3).多态:重载(如js默认不支持一个函数名执行不同结果,但是函数自带argunment可接收传入参数的类数组)和重写(如原型链上同一个函数,在不同位置具有不同函数)。
4.ES5:
1).严格模式:包括js文件或script标签下,及单个函数内顶部,"use strict";
(1)具体:禁止给未声明的变量赋值,禁止将默认失败升级为错误,禁止递归,匿名函数的this不在指向全局。
2).保护对象:
⑴ 保护属性:命名属性(数据属性和访问器属性)和自有属性;数据属性的四大特(value,writable,enumerable,configurable),访问器属性的四大特性(set(){},set(){},enumerable,configurable);
⑵ 保护结构:阻止扩展(Object.preventExtensions(obj)),密封(Object.seal(obj)),冻结(Object.freeze(obj))。
3).Object.create();基于现在父对象,创建一个子对象并扩展其自有属性,var child=Object.create(father/*,{设置4大属性})。
4).call(),apply(),bind();call()和apply()在调用函数时替换不正确的this指定的对象,前者需要独立传参,后者需要把参数放进数组中传入。bind()是基于现有函数,创建一个新函数,并永久绑定this指定对象。var keys=Object.keys(obj),表示获取对象obj所有属性名组成的数组。
5.ES6:
1).let:替代var,避免声明提前,相同作用域内不允许重复let第二个变量,仅在当前作用域内有效,避免全局污染,增加选择语句的的块级作用域{}。
2).参数增强:
(1)默认值default; 参数=default值 => 参数=参数 || 默认值;
(2)剩余参数;(参数1,...,...arr),代替arguments传参。类数组对象转为数组: var arr=Array.prototype.slice.call(arguments) //arguments.slice()//完整复制arguments。
(3)打散数组;(...arr),代替apply();
3).箭头函数:对匿名函数的简化。
4).模板字符串: `...${}...`;
5).解构:数组解构,对象解构,函数参数定义和调用时解构;
6).for...of:for(var elem of arr){},简化for()循环索引数组。
7).简化构造函数和原型对象:
(1)class定义; class 类型名(参数列表){
this.属性名=参数;
}
方法名(){}
...
}
⑴ 用class封装构造函数和原型对象方法定义 。
⑵ 构造函数名提升为class名,构造函数更名为固定的关键词Constructor。
⑶ 直接写在class中的方法,默认都保存在原型对象中。
(2)继承:
⑴ extends fhther => Object.setPrototypeof(child,father);
⑵ super(...) => 抽象父对象构造函数名.call(this,...);
(3)访问器属性:其前2大特性改为get 访问器属性 (){},set 访问器属性(val){};
8).Promise(.all):对回调函数的规范写法,避免回调深渊。
(1) 定义接收回调函数的主函数:function fun(){
return new Promies(function(){
....callback();......
})
}
(2) 调用主函数执行,并传入下一个要执行的回调函数:
fun().then(callback);
(八)DOM;
1.定义;Document Object Model,统一操作页面内容的API,几乎100%兼容所有浏览器。
1).原生js:包括ECMAScript,DOM,BOM。
2.DOM Tree;
1).定义:所有网页内容在内存中都是以树型结构存储,更好的体现了层次关系。
2).内容:根节点对象—document,节点对象(所有元素,文本,注释...)——node。
3).三大属性:
(1)nodeType; document——9。
element——1。
attribute——2。
text——3。
(2)nodeName; document——#document。
element——全大写的标记名。
attribute——属性名。
text——#text。
(3)nodeValue; document——null。
element——null。
attribute——属性值。
text——文本内容。
3.查找;
1).四种方法;
(1) 不需要查找就可直接获得元素。
document.documentElement ->html;
document.head -> head;
document.body -> body;
document.forms[i/id/name] -> 某个form;z
(2)按节点查找;节点树:包含一切网页内容的DOM Tree。
elem.parentNode; elem的父节点。
elem.childNodes; elem下所有子节点的动态集合。
elem.firstChild/lastChild; elem下首/尾节点。
elem.previousSibling; elem前一个节点。
elem.nextSibling; elem后一个节点。
元素树:仅包含元素的DOM tree。
elem.parentElement; elem 的父节点。
elem.children; elem的所有子节点,动态集合。
elem.firstElementChild/lastElementChild;
elem.preciousElementSibling;
elem.nexElementSibling;
查找一个元素的所有子元素方法? 1.递归(深度优先遍历); 2循环(节点迭代器); |
(3)按照HTML查找;
⑴ 按照id查找:var elem=document.getElementById("id");返回一个元素或null。
⑵ 按照标签名查找:var elems=parent.getElementsByTagName("标签名");返回多个元素组成的动态集合或空集合。
⑶ 按name查找:var elems=document.getElementsByName("name");返回多个元素组成的动态集合或空集合。
⑷ 按class查找:var elems=parent.getElementsByClassName("className");返回多个元素组成的动态集合或空集合。
(4)按照选择器查找;
⑴ 查找一个元素:var elem=parent.querySelector("选择器");
⑵ 查找所有元素:var elem=parent.querySelectorAll("选择器");返回非动态集合或空集合。
4.修改;
1).内容:(1)elem.innerHTML——获取/修改双标记元素内容;
(2)elem.textContent——获取/修改文本内容;去内嵌标记转义文本;
(3)elem.value——获取/修改单标记内容;
2).属性:(1)核心DOM——支撑一切结构化文档(html,xml)的DOM API;
⑴ var value=elem.getAttribute("属性名")——获取属性值;
⑵ elem.setAttribute("属性名","值")—修改属性值;
⑶ elem.hasAttribute("属性名")—判断属性是否存在;
⑷ elem.removeAttribute("属性名")——移除属性;
(2)HTML DOM——对部分核心DOM API的简化;
⑴ var value=elem.属性名——获取属性值;
⑵ elem.属性名=值——修改属性值;
⑶ elem.属性名 !="";判断属性是否存在。
⑷ elem.属性名="";移除属性。 例外:class=>className;
(3)状态属性——selected,disabled,checked。三大状态属性值类型是bool,只能用HTML DOM操作,因为核心DOM只能操作值类型是字符串的。且三大状态属性都有对应的选择器::selected, :disable, :checked。
(4)自定义拓展属性——用于选中触发事件元素,保存业务数据。
⑴ 定义和选择器:
⑵ 访问方法:无法用HTML DOM访问,只能用核心DOM访问或用 HTML5访问。在HTML5中用elem.dataset.属性
名访问修改。
3).样式:
(1) 内联样式;
⑴ 修改:elem.style.属性名="值"; 属性名一律去_变驼峰。
⑵ 获得完整计算后的样式:var style=getComputedStyle(elem); var value=style.属性名。计算后的样式只读不能修改,且可能影 响其他元素的样式。
(2) 样式表(内部/外部);
⑴ 获得样式表对象:var sheet=document.styleSheets[i];
⑵ 获得要修改属性所在的cssRule:var rule=sheet.css Rules[i]; 一个cssRule为一个{},如果是keyframes,还需要再次获得rule下的cssRule。
⑶ 修改rule.style的css属性:rule.style.属性名="值";可 以用class批量应用修改样式。
5.添加与删除;
1).添加:(1)创建空元素,var elem=document.createElement("标签名");
(2)设置关键属性,elem.属性名=值;
(3)将新元素添加在指定父元素下,
末尾添加——parent.appendChild(elem);
中间插入child——parent.insertBefore(elem,child);
替换child——parent.replaceChild(elem,child);
2).优化以上添加删除操作,减少对DOM树的操作次数。
(1) 同时添加父和子元素,先将子元素添加到父元素,再将父元素一次性添加到页面。
(2) 同时添加多个平级的子元素,可借助临时保存在文档片段,最后在一次性添加到页面,然后文档片段立即释放,不占据内存。
步骤如下:⑴ 创建临时文档片段;
var frag=document.createDocumentFragment();
⑵ 将多个平级子元素添加到临时文档片段中;
frag.appendChild(child);
⑶ 将临时文档片段添加到页面;
parent.appendChild(frag);
6.HTML DOM 常用对象;即简化部分HTML元素操作的API。
1).Image:代表页面上一个元素; 创建,var img=new Image();
2).Select:代表页面上一个
⑴ 属性:select.selectedIndex,获得当前select中选择项的下标位置。
select.value/innerHTML,获取当前select的value值/内容。
select.options,获取当前select的所有option集合。
select.options.length,获取当前select的option总个数。
select.options.length=0,清空所有option。
select.length => select.options.length。
⑵ 方法:select.add(option) => select.appendChild(option),但是add不支持frag,append支持frag。
select.remove[i],移除i位置的option。
3).Option:代表页面上一个
⑴ var option=new Option(text,value);表示创建option并添加其属性及值option.innerHTML=text,option.value=value。
4).Table:处理行分组thead,tbody,tfoot。
⑴ 创建行分组:var thead/tbody/tfoot=table.createTHead/TBody/ Tfoot();
⑵ 删除行分组:table.deleteTHead/TFoot(); 不能删除tbody,因为一个 表可能有多个tbody。
⑶ 获得行分组:table.tHead/tFoot/tBodies[i];
5).行分组thead/tbody/tfoot,处理着具体的每行;
⑴ 添加行:var tr=行分组.insertRow(i); i为具体的行,i=0为行分组下的首行,不写i为行分组下的尾行。
⑵ 删除行:行分组.delectRow(i);i是行相对行分组下的位置。无法直接获取。tr.rowIndex表示tr在整个表中的相对位置。删除行:table.deleteRow(tr.rowIndex)。
⑶ 获取行:行分组.rows[i];
6).行处理着每个单元格;
⑴ 添加格:var td=tr.insertCell(i);不写i为行下的尾列,不能添加th。
⑵ 删除格:tr.deleteCell(i);
⑶ 获取格:tr.cells[i];
7).Form;代表页面的一个