1. 完整的js组成(即原生的js):
(1)ECMAScript:规定了js的语法,类型,句子,关键字,保留字,操作符,对象。
(2)DOM:提供访问和操作网页内容的方法和接口。
(3)BOM:提供与浏览器交互的方法和接口。
2. 在html中使用js的方法:
(1)将代码写入<script>/*js代码区域*/</script>里。
(2)<script src="js外部文件url"></script>
优点:引入外部文件的优点,可维护性,可缓存性(再次使用不需要下载),适用于xhtml页面。
script标签的5大常用属性:
a. async,可选,表示应该立即下载脚本,但是不妨碍页面其他操作(如下载其他资源/等待加载脚本,只对外部脚本有效)。
b. charset,可选,指定代码的字符串。
c. defer,可选,表示文档可以延迟到文档完全被解析和显示之后才执行(仅对外部文件有效)。
d. src,可选,外部js文件的相对/绝对路径。
e. type,可选,代码使用的脚本语言的内容类型,默认text/javascript。
script标签在html页面的位置:
传统:将js和css文件都放在head标签里面;
缺点:浏览器遇到body标签才开始呈现内容,这就意味着必须等到全部js代码被下载,解析,执行之后才会呈现内容,就会出现页面空白和明显的延迟。
现在:将js代码文件放在body标签的最后面,为此,把延迟脚本放在页面底部仍然是最佳选择。
注意:
(1)在解析(包括下载该文件)script标签的嵌入代码/引入外部js代码文件时,页面的处理会暂停。
(2)script标签不存在defer和async时,浏览器会按照script标签在html页面出现的先后顺序从上到下依次进行解析。
3. 基础语法:
(1)(变量、函数名和操作符)区分大小写。
(2)命名规则:第一个字符必须是字母、_或$,其他的必须是字母、数字、_或$。
(3) 注释:// 和 /**/。
(4) 严格模式:'use strict';
(4.1)在全局script下顶端或在函数下顶端(前可有注释)声明,否则无效。
(4.2)严格模式的执行:
1.不允许全局变量,否则语法错误。
2.静默失败升级为错误。
3.this不在默认指向全局。
如function f(){
return !this; //返回false,因为在非严格模式下 this指向全局,!this表示不是
} //指向全局,所有是错误的 。
但是function f(){
"use strict"; // 返回true,因为在严格模式下,this指向undefined,所
return !this; // 以!this表示不指向全局指向undefined。
}
4.禁止调用argunments,callee,caller,禁止递归函数,否则语法错误。
5.函数参数重名则报错,对象重名也报错,对对象的四大只读属性赋值修改也会报错。
6.禁止在非函数的代码块内声明函数,如在条件和循环语句中声明函数是语法错误。
(5)分号:语句以分号‘;’结尾,可以省略,但是推荐写上分号;
(6)变量:命名必须符合(2)命名规则,分类为全局变量和局部变量,注意在js默认的变量/函数名
的声明提前;
(7)数据类型包括:
基础类型:Undefined、Null、Boolean、Number和String。
引用类型:Object。
(7.1) typeof操作符而非函数:判断数据的类型,可以判断string、boolean、underfined、number、object、function,但是不能区分Object和Array。用法:typeof a 或typeof (a)。
(7.2)underfined:未定义声明或声明未赋值或声明赋值为underfined的变量/函数。
(7.3)null:空对象,null==underfined为true,但是null===underfined为false。
(7.4)boolean:true/false区分大小写。
(7.5)number:
a. 支持十六进制(前2位必须是0x后面接0~9及A~F和a~f),八进制(以0开始接0~7,超出
该范围前面0被忽视,后面解析为十进制),十进制,科学计数法(e)。在计算时,八和十六进制都自动最终
转化为十进制。
b.浮点数小数点后至少有一位数字,最高精度为17位小数,但是注意程序中0.1+0.2 !=0.3;
c. 大多浏览器能保存的数值范围5e-324~1.7976931348623157e+308超出这个范围为
+/-infinity无穷。
(7.6) NaN:非数值;
a. 任何操作NaN都会返回Na;
b. NaN与任何值(包括自身NaN)都不相等;
c. isNaN():判断是否为非数值的函数,任何不为数值/不能转换为数值的值都会返回true;
如true,15,'15'都能转为数值返回false,而'abc','a15','15a'返回true;
(7.7) 数值的转换,将非数值转换为数值:Number(),parseInt(),parseFloat()。
a. Number()的转换:
a.1 布尔值的true/false转化为0和1。
a.2 null转换为0。
a.3 underfined转换为NaN。
a.4 字符串:纯数字(整数、浮点数、十六进制数)字符串转化为十进制数值,如'1.5'转
化为1.5,'012'为12。空字符串转为为0。除此之外转换为NaN,如‘a15’,'15a'都为NaN。
b. parseInt()和parseFloat(num,n)的转换:num为转换的值,n为转换的进制类型;
b.1 字符串:如果第一个字符不是数字字符或者负号,返回NaN ;如果字符串的第一
个字符串是数字,就会识别直到第一个非数字字符整数/小数; 如果n为16进制字符串可以不带'0x';
如parseInt('AF',16)为数值175,而parseInt('AF')为NaN;
(7.8) String类型: 由''或“”表示;
a. 转义符\;
\n 换行;
\t 制表;
\b 空格;
\r 回车;
\\ 斜杠;
\' 单引号;
\" 双引号;
b. 转换为字符串;
b.1 str.toString(n):n为可选参数,转换为2/8/10/16进制,默认为10进制;
b.2 String(str):null返回'null',underfined返回'underfined',其他与b.1一致;
(7.9) Object类型:
a. var obj=new object(): 不推荐省略括号;
(8)操作符(运算符):
(8.1) 算术运算符:+、-、*、/、++、--、%;在执行算术运算符时,先通过
parseInt/patseFloat()转换为为数值或NaN,再进行算术运算;
(8.2) 按位运算符:&、|、^、<<、>>;
(8.3) 逻辑运算符:&&、!、||;短路逻辑 。
(8.4) 比较运算符:<、>、<=、>=、!=、==、===、!==;将字符串/布尔值转换为
数值再进行比较运算,如果是2个字符串比较,则比较字符编码值;
(8.5) 条件(三目)运算符: ? : ;
(8.6) 赋值运算符:=、+=、-=、*=、/=、%=;
(8.7) 逗号运算符:var a , b , c ; var n=(1,2,3,4);//结果n为0;
以下是操作符(运算符)的先后顺序:
(9)逻辑结构: 循环条件/选择语句;
(9.1) 条件语句:
a.1 if () else () ; if () else if(){}else {};
a.2 switch (表达式) {
case 值:
continue; //跳过此次,执行后面代码
default:
break; //终止后面代码
}
(9.2) 循环语句:
a.1 for () {循环主体} ;
a.2 while () {} ;
a.3 do {} while () ;
a.4 for ( in ) {};
4. 变量、作用域、内存问题:
(1) js存在2中不同类型的值:基础类型值(underfined,null,boolean,number,string)和引用类型值
(object)。其中基础类型值是按值访问的,可以操作保存在变量中的实际的值。而操作对象时,当复制保存
着对象的某个变量时,操作的是对象的引用,而为对象添加属性时,操作的是实际的对象。
注意:不能给基础类型的值添加属性,会underfined;
如1:var name=new Object();
name.age=27;
alert(name.age); //输出为27,如果name对象或其属性age不被销毁,则会一直存在age=27;
如2:var name='Ace';
name.age=27;
alert(name.age); //不会报错,会输出underfined,即不能为基础类型值添加属性;
(1.1)定义基础类型值和引入类型值方式一致:创建一个变量并该变量其赋值。
(1.2)复制基础类型值和引入类型值:
基础类型值的复制:创建一个新的相同的值,赋值给新的变量;
引用类型值的复制:创建一个新的引用类型的栈地址,但是和引用类型变量名栈地址指
向同一个栈的值;所有修改原/新引用对象,会改变栈里同一个指向的值;
(1.3) js中所有函数的参数(基础类型值和引用类型值)都是按值传递:
如1:function setN(obj){
obj.name='Ace';
obj=new Object();
obj.name='ss';
}
var person=new Object();
setN(person);
console.log(person.name); //输出结果为Ace,因为将person对象作为参数传递到
setN()函数中,其person对象的name已经被设置为Ace,再将新对象new Object()赋值给setN()的参数
时。
(1.4)检测数据类型:
a. typeof 用于检测基础类型值,用法:typeof a或typeof (a);
b. instanceof用于检测引用类型值,用法:a instanceof Object/Array;
(2)作用域:包括全局作用域和局部作用域;
如图为作用域的解析过程:在函数执行前ecs会先生成一个主函数main(),在此自上而下解析代码,先是
存在window中的全局变量a和fun,函数的scopes属性会使得其作用域自动执行上一级作用域(如果没有依
次往上直到window),在调用函数时,ecs会主动生成一个活动对象AO用于保存函数里面的作用域,当调
用函数时,会从该函数的活动对象的作用域依次顺着作用域链往上到window查询调用函数需要的变量,直
到找到为止,函数执行完之后,活动对象AO立即释放消失。
(3)垃圾回收机制:js有自动垃圾回收机制;
手动垃圾回收(解除引用):将其赋值为null, obj=null即可;
5. 引用类型:Object、Array、Math、Data、RegExp、Function、内置对象;
(1)object:数组
(1.1) object的2种创建方式:
a. var obj={};
b. var obj=new Object();
注意:object对象的属性方法,可以通过点‘.’和中括号'[]'访问。其中点访问的优点是可以通
过变量来访问属性。如果属性名中包含了会导致语法错误的字符如空格,或使用了关键字/保留字,则需要
中括号访问。
(2)array:
(1.1)array的2种创建方式:
a. var arr=[ ];
b. var arr=new Array();
注意:new Array(3)表示创建length为3的数组,new Array("a1",'a2','a3');如果将数组的
length属性设置大于数组的项值(arr.length-1<arr.length=100),就会将arr末尾新增到100项,超出没有赋
值的项就会默认值为underfined;
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里面的值,返回布尔值。
(1.2) array的常用方法(API):
1).遍历数组;for(){}或for(..in..){};
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...元素,返回新数组。
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();表示把数组按,号隔开元素转换为字符串。可以把二维数组的每个元
素都隔开转为字符串。
(2)arr.join("分隔符");表示把数组的元素按"分隔符"转换为字符串。
6).定位与倒序;
(1)var i=arr.indexOf("字符",fromi);
(2)var i=arr.lastIndex("字符",fromi);
(3)arr.reverse();将原数组倒序排列,返回原数组。
7).迭代;
(1)var bool=arr.every/some(function(elem,i,arr){return});表示判断数组中是否所
有元素都符和条件/是否包含符合条件的元素。
(2)arr.foreach/map(function(elem,i,arr){return});对数组中每个元素执行相同的操
作并返回原数组/新数组。
(3)arr.filter(function(elem,i,arr){return});从原数组中选取符号条件的元素组成新数
组。
(4)arr.reduce(function(prev,elem,i,arr){});数组中每个元素的累加和。
(3) Data:日期时间,var date=new Date() ;
getTime() 返回表示日期的毫秒数;1525916922181
setTime(毫秒) 以毫秒数设置日期,会改变整个日期
getFullYear() 取得4位数的年份(如2007而非仅07)
getUTCFullYear() 返回UTC日期的4位数年份
setFullYear(年) 设置日期的年份。传入的年份值必须是4位数字(如2007而非仅07)
setUTCFullYear(年) 设置UTC日期的年份。年份值必须是4位数字(如2007而非仅07)
getMonth() 返回日期中的月份,其中0表示一月,11表示十二月
getUTCMonth() 返回UTC日期中的月份,其中0表示一月,11表示十二月
setMonth(月) 设置日期的月份。传入的月份值必须大于0,超过11则增加年份
setUTCMonth(月) 设置UTC日期的月份。月份值必须大于0,超过11则增加年份
getDate() 返回日期月份中的天数(1到31)
getUTCDate() 返回UTC日期月份中的天数(1到31)
setDate(日) 设置月份中的天数。传入的值超过了该月中应有的天数,则增加月份
setUTCDate(日) 设置UTC月份中的天数。传入值超过了该月的天数,则增加月份
getDay() 返回日期中星期的星期几(其中0表示星期日,6表示星期六)
getUTCDay() 返回UTC日期中星期的星期几(其中0表示星期日,6表示星期六)
getHours() 返回日期中的小时数(0到23)
getUTCHours() 返回UTC日期中的小时数(0到23)
setHours(时) 设置日期中的小时数。传入的值超过了23则增加月份中的天数
setUTCHours(时) 设置UTC日期中的小时数。传入的值超过了23则增加月份中的天数
getMinutes() 返回日期中的分钟数(0到59)
getUTCMinutes() 返回UTC日期中的分钟数(0到59)
setMinutes(分) 设置日期中的分钟数。传入的值超过59则增加小时数
setUTCMinutes(分) 设置UTC日期中的分钟数。传入的值超过59则增加小时数
getSeconds() 返回日期中的秒数(0到59)
getUTCSeconds() 返回UTC日期中的秒数(0到59)
setSeconds(秒) 设置日期中的秒数。传入的值超过了59会增加分钟数
setUTCSeconds(秒) 设置UTC日期中的秒数。传入的值超过了59会增加分钟数
getMilliseconds() 返回日期中的毫秒数 ,注:UTC为世界统一时间
getUTCMilliseconds() 返回UTC日期中的毫秒数
setMilliseconds(毫秒) 设置日期中的毫秒数
toDateString() Thu May 10 2018
toTimeString() 09:46:16 GMT+0800
toLocaleDateString() 2018年5月10日
toLocaleTimeString() 上午9:47:20
toUTCString() Thu, 10 May 2018 01:47:44 GMT
(4)RegExp:正则
(4.1)创建方法:
1. var reg=/正则/ig; // i为忽视大小写,g为全部,m为换行继续查找正则匹配
2. var reg=new RegExp("正则","ig");
(4.2)应用:
1. 验证格式:var bool=reg.text(str); 必须^和$。
2. 查找敏感词及位置:var arr=reg.exec(str); arr=[0:敏感词, index:位置],但是只能找到一
个就返回,找不到返回null。
(4.3)RegExp实例属性:
1. reg.global: 判断reg是否设置了g ;
2. reg.ignoreCase: 判断reg是否设置了i ;
3. reg.multiline: 判断reg是否设置了m ;
(5)Math:数学数字
(5.1)API: Math.ceil(num)——取上整值;
Math.floor(num)——取下整值;VS parseInt(num);
Math.round(num)——四舍五入;VS num.tofixed(d);
num.Math.pow(底数,冥)——乘方;
Math.sqrt(num)——开方;
Math.max/min((...arr)/参数1,参数2,...);
Math.random()——0-1之间的随机数;
Math.floor(Math.random()*(max-min)+min):随机生成min~max的数字。
Math.abs(num) ——num 的绝对值
Math.asin(x) ——x 的反正弦值
Math.exp(num) ——Math.E 的num 次幂
Math.atan(x) ——x 的反正切值
Math.log(num) ——num 的自然对数
Math.atan2(y,x) ——y/x 的反正切值
Math.pow(num,power) ——num 的power 次幂
Math.cos(x) ——x 的余弦值
Math.sqrt(num) ——num 的平方根
Math.sin(x) ——x 的正弦值
Math.acos(x) ——x 的反余弦值 Math.tan(x) 返回x 的正切值
Math.E—— 自然对数的底数,即常量e的值
Math.LN10—— 10的自然对数
Math.LN2 ——2的自然对数
Math.LOG2E—— 以2为底e的对数
Math.LOG10E ——以10为底e的对数
Math.PI ——π的值
Math.SQRT1_2 ——1/2的平方根(即2的平方根的倒数)
Math.SQRT2 ——2的平方根
(6)String:字符串
(6.1)String VS数组:相同点:1.下标。2.length。3.for遍历。4.slice()截取。
不同点:类型不同,所有API不通用。
(6.2)大小写的相互转换:str.toUpperCase():返回新字符串。
str.toLowerCase():返回新字符串。
(6.3)字符串与unicode的转换:var unicode=str.charCodeAt(字符串下标=0);
var str=String.fromCharCode(unicode);
(6.4)截取子字符串:var str1=str.slice(start,end):返回新字符串。
var str1=str.substring(start,end):返回新字符串。
var str1=str.substr(start,n):返回新字符串。
(6.5)获取指定位置i的字符:var str1=str[i];
var str1=charAt(i);
(6.6)获取关键字符的位置:var i=str.indexOf("关键字符",fromi=0);
var i=str.lastIndex("关键字符");
(6.7)通过正则获取敏感词位置:var i=str.search(/正则/);
(6.8) 通过正则获取敏感词:var str1=str.match(/正则/ig);ig表示不区分大小
写,全部敏感词获取。
(6.9)替换(删除)字符串的敏感词:var str1=str.replace(/正则/ig,"新内容");
var str1=str.replace(/正则/ig,function(kw){return
kw=?});
(6.10)切割字符串成数组:var arr=str.split("自定义切割符");
var arr=str.split(/正则表达式/);
(6.11)去掉字符串的首尾空格:var str1=str.trim();
(6.12)将一个/多个字符串拼接:var str0=str.concat('str1','str2',...);
(7)URL编码、解码:
(7.1)编码:因为有效的url不能包含某些字符( 如空格 )所有对url进行编码( 用utf-8替代所有无效
的字符 )以便发生给浏览器解析;
a. encodeURI(): 主要用于整段url编码,单仅编码空格为%20;
b. encodeURIComponent():主要用于某段url编码,对所有非字母数字字符编码,常用API;
(7.2)解码:
a. decodeURI():针对encodeURI()编码后的代码进行解码;
b. decodeURIComponent():针对encodeURIComponent()解码;
(8)eval():完整的ECMAScript 解析器;
如:eval("alert('hi')"); //输出hi;
var m='hi';
eval("function get(){alert(m)}"); //调用get()输出hi;
注意:eval()里面的字符串参数只有在eval()执行时才创建,在严格模式下,以上案例为错误,且不能为eval='hi'赋值;
(9)Error:保存错误的对象。
(9.1)错误处理:即即使程序出错,也不会中断退出的机制。
(9.2)操作:try{
//可能出错的正常代码
}catch(err){
//出错后执行的代码,提示用户,保存进度,记录日志/或throw new //Error("错误信息提示")
}。
(9.3)六种常见错误类型:
1. SyntaxError——语法错误;
2. ReferenceError——引用错误,即需要的变量没有找到;
3. TypeError——类型错误,即错误调用函数或对象的API;
4. RangeError——范围错误,即参数的范围错误;
5. URLError——URL格式错误;
6. EvalError——eval()错误,一般很少见;
6. 面向对象