看书不懂的地方
eval函数?
try-catch机制不太懂,没实践过
oops是什么???
with函数弊端没看
eval函数没看
正则表达式没看
脚本运行规则
编写脚本
js中的文档写入
<script>
document.write("<h1>Hello,World!</h1>")
//document表示DOM文档对象
</script>
注意 动态脚本的写法
如果你这么写就不能执行,只是写出来:
document.write("f(); ");
document.write("function f(){ ");
document.write("alert(1);");
document.write("}; ");
如果这么写会被正常执行
document.write("<script> ");//写上script标签
document.write("f(); ");
document.write("function f(){ ");
document.write("alert(1);");
document.write("}; ");
document.write("</script> ");
存在兼容性问题
script标签的属性
必选属性:加上type=“text/javascript”,这个表示当前脚本为js,如果不加可能别人修改过默认脚本,就会出点问题。
async和defer还是不太理解???看下视频把。
脚本位置
为了避免出现延迟,优先显示整个页面的样式,所以把script放在body的最后位置,网页会看起来快
注意:XHTML中要写defer=“defer” async="async"
但是,延迟脚本放在页面底部是最佳选择,因为小众浏览器没有defer属性
总结
<script src="a.js"></script>
浏览器会做如下处理
- 停止解析 document.
- 请求 a.js 执行 a.js 中的脚本
- 继续解析 document
defer 延迟执行
<script src="d.js" defer></script>
<script src="e.js" defer></script>
- 不阻止解析 document, 并行下载 d.js, e.js
- 即使下载完 d.js, e.js 仍继续解析 document
- 按照页面中出现的顺序,在其他同步脚本执行后,DOMContentLoaded 事件前 依次执行 d.js, e.js。
async 异步响应
<script src="b.js" async></script>
<script src="c.js" async></script>
- 不阻止解析 document, 并行下载 b.js, c.js
- 当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在 DOMContentLoaded 事件前或者后 )
1.JS解释过程
两个阶段:
预处理(预编译):把JS代码转成字节码
执行期:字节码转成二进制机械码
alert(a); //undefined
var a=1;
alert(a); //1
这个不会报错****但是第一个显示undefined:
因为预处理阶段对声明的变量和函数会全部处理,所以第一个执行时存在变量a,但是在执行期是顺序执行,存在的变量a没被赋值,所以是undefeined.
同理:
f(); //1
function f(){
alert(1)
}
但是
f(); //报错:语法错误
var f = function(){
alert(1)
}
因为第二个相当于声明了一个变量f,在执行阶段变量f又加载不到赋的值;第一个f()是函数,可以直接加载出来。
2.JS加载顺序
两个代码块之间的变量和函数是可以共享的!!
但是你得先全部加载才能用的上,所以需要使用window.οnlοad=function(){}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<script>
window.onload=function(){
//前面的块也能用后面块的变量和函数
alert(a);
f();
}
</script>
<script>
var a=1;
function f(){
alert(1);
}
</script>
</head>
<body>
</body>
</html>
所以改变代码执行顺序有很多方法:onload,鼠标事件,键盘事件,时钟触发器等
3.错误处理机制
RangeError:数组超出合法范围
ReferenceError:读取不存在的变量错误
try-catch
try{
//可能会导致错误的代码
}
catch(error){
//在错误发生时怎么处理
}
例如:
try{
a+b;
}
catch(error){
alert(error.message);
}
finally
var a=function(){
try{
return 2;
}
catch(error){
return 1;
}
finally{
return "无论如何都会执行";
};
};
console.log(a());
无论怎么样都会执行finally语句,所以不管有没有错误,都是输出0
IE7这里有个bug(有catch才能有finally),IE8已修复
throw
遇到throw时,代码会立即停止执行,当tyr-catch语句捕获到被抛出的值时,代码才会继续执行
var a = "hello";
try{
alert(a); //如果是不存在的变量,则抛出异常,将直接跳到catch里面执行(throw定义异常也不会被抛出)
throw "不存在"; //定义抛出异常
alert("I am try"); //只要上面的语句出现错误或者throw语句这句将不会被执行
}
catch(err){ //如果try中发现错误,则执行catch中的语句,如果没有错误,则跳过catch
alert(err) //接收设置的throw错误异常,如果没有则抛出根据情况默认错误
alert("错误弹出"); //被执行
}
finally{
alert("无论如何都会执行");
}
var b="world";
if(b){
document.write(b);
}
else{
alert("error");
}
实例:
function process(values){
if(!(values instanceof Array)){
throw new Error("process():参数必须为数组。");
};
values.sort();
console.log(values);
var a=[];
for(var i=0;i<values.length;i++){
if(values[i]>100){
// return values[i];//执行了return之后,就不会再执行其他的内容
//相当于返回了结果且break
a.push(values[i]);
}
};
return a;
}
console.log(process([1,2,9897,5654,212,102,654]))
这里有两个注意点:
1.return的特点:返回结果且直接break循环
2.throw被执行后会中止代码
4.系统为什么会自动报错
window标签里自带属性onerror
window.onerror(错误消息,错误所在URL,行数)
基本语法
1.Number注意事项
易错问题总结
1.0开头是八进制的问题:
parseInt("1.23"); //返回1
parseInt(".23"); //返回NaN parseInt不允许.开头
//但是0开头被认为是八进制
console.log(parseInt("0.23",10)); //把十进制里的0.23转为十进制整数 输出0
console.log(parseInt("10",8));//把八进制的10转为十进制整数 输出8
2.parseFloat只支持十进制形式的字符串
3.+是字符串,*是数字
var a=1;
var b="1";
alert(a+b); //返回“11”
var a=1;
var b="1";
alert(a+(b*1)); //返回数值2
数字保留问题
toFixed
toString((20.35).toFixed(3)); //返回20.350
toExponential(3) 科学计数法保留3位且时四舍五入
toPrecision(3) 只科学计数法时保留3为且后面直接舍去
十六进制:0x或0X开头
var num=0x1F4;
alert(num); //输出500,16进制直接转10进制
不建议使用八进制,以0开头,容易误解析为十进制
var a=Math.floor(20.5); //输出50,下舍入
var a=Math.round(20.5); //输出21,四舍五入
计算问题
0.1+0.2=0.3000000004
小数计算的天生bug:二进制的浮点数不能正确处理十进制的小数?
所以要(1+2)/10,尽量用整数进行算
toString的新用法
返回目标进制的对应字符串
var a=32;
console.log(a.toString(2)); //返回二进制下32的字符串“100000”
console.log(a.toString(16)); //返回16进制下32的字符串“20”
//注意不能直接数值用
console.log(32.toString(16)); //报错
console.log((32).toString(16)); //正常,"20"
isNaN和isFinite的产生
因为:
typeof NaN==="number" //true
NaN===NaN //false
NaN!==NaN //true
所以typeof无法区分数字和NaN
isNaN(NaN) //true
isNaN(0) //false
isNaN("0") //false
isNaN("oops) //true
更好用的,isFinite,能筛选掉NaN和Infinity(无穷大)
用于判断一个值是否可用作数字
function isNumber(value){
return typeof value==="number"&& isFinite(value);
}
2.字符串注意事项
换行用\n,
可以用.length查看字符串长度
alert("学而不思则罔,思而不学则殆".length) //返回13
转义字符串
书P44
3.Boolean注意事项
false:undefined, null, " ", 0, NaN
其他都为true
三目运算符
强制转换成boolean
var a=1;
var b=2;
!!a //true
var b=new Boolean(b); //返回true
//但是typeof(b)是一个object 因为他是个对象!!!
1、什么是三目运算:(布尔表达式 ? 值0:值1;)
5>3?alert('5大'):alert('3大');
//即if(5>3){alert('5大')}else{alert('3大')};
注意:三目运算和if(){}else{}的 区别是三目运算有返回值
例如:
var max = a>b?a:b;
多条件的三目运算怎么写:
实例:根据学生成绩判定ABCD四个等级
var result = (sc<0 || sc>100) ?("分数无效"):
sc>=90?("A"):
sc>=80?("B"):
sc>=60?("C"): ("D");
直接带返回值!!!
Boolean在三目运算符中的应用
var a;
a=a?a:1; //a不空则还是a,a为空则赋值1
4.Null是object,undefined是Undefined类型
由于null是object,所以检测数据类型的时候可以这样
function type(o){
return (o===null)?"null":(typeof o)
}
alert(null===undefined); //true 都是0
alert(typeof null === typeof undefined); //flase 不同类!
5.严格模式
有些语句在严格模式下不能运行,需要掌握严格模式
放在首行!!!
"use strict"
全局模式(加在script里的首行),严格说是加载产生实际运行结果的语句前才是全局模式
局部模式(加载函数内部首行,只有函数执行)
模块模式 定义模块或者库时用
(function(){
"use strict";
//继续写代码
})();
严格模式的限制
东西有点多啊,第二遍再看,第一遍看着没啥用哈
1.显示声明变量:要加var
2.静态绑定:
正常模式下,js有些属性和方法属于哪个对象实在运行时才确定,严格模式只允许静态绑定。 严格模式利于阅读: 禁止使用with语句 创设eval作用域
with语句
在指定的代码区域, 直接通过节点名称调用对象。
var obj = {
a: 1,
b: 2,
c: 3
};
// 正常方法我如果取修改obj里面abc的值要这么写
obj.a = 2;
obj.b = 3;
obj.c = 4;
with (obj) { //但是用with就这么写
a = 3;
b = 4;
c = 5;
}
弊端
原理分析看不太懂,后面再看
https://blog.csdn.net/zwkkkk1/article/details/79725934
所以不推荐用,知道就行
eval语句 → evaluate评价评估
也没有看 回头看 第一遍不扣细节
https://www.jianshu.com/p/d1afad1c76a9
反正也是不推荐用
3.增强的安全措施
禁止this关键字指向全局对象
禁止在函数内部历遍调用栈
4.禁止删除变量
6.检测数据类型
constructor更细致
var o={};
var o=[];
alert(o.constructor);//输出array类型
检测还有toString 看不太懂回头看 P54
7.字符串转换
用a+“” 万物皆是字符串
var a=[1,2,3];
a=a+"";
alert(a); //返回字符串"1,2,3"
var a=function(){
return 1 ;
};
a=a+"";
alert(a) //返回字符串"var a=function(){return 1 ;};"
正则表达式,不会,后面看吧
https://www.runoob.com/js/js-regexp.html