一,json的话属性名必须加双引号 (人为规定--防止跟对象一样)
1.JSON是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象就是本地用的,JSON是用来传输的)
2.JSON.parse(); string-->json
3.JSON.srtingify(); json--->string
var obj ={
"name" : "abc";
"age" : 123
}
var str =JSON.stringify(obj); 会把这个json格式的obj转换成字符串形式,str会输出"{"name":"abc","age":123}"
parse把他上面个字符串解析成对象 JSON.parse(str)
二,异步加载js
javascript 异步加载的三种方案
1.defer异步加载,但要等到dom文档全部解析完才会被执行(dom树生成完,就是标签从第一行到最后一行全部生成了),只有IE能用,也可以将代码写到内部
<script type="text/javascript" src="tools.js" defer="defer">
可以写到内部,会让内部的js文件异步的
</script>
也可以不写defer="defer" 可以直接写defer系统会默认加上
2.async 异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script标签里。
跟上面那个defer基本类似,他是W3C标准方法,IE9以上和其他浏览器都可以用
第一个跟第二个执行时不阻塞页面
3.创建script,插入到DOM中,加载完毕后csllBack --->下图
function loadScript(url,callback){ //-->callback回调函数,当满足一定条件之后执行的叫回调函数
var script = document.createElement('script');
script.type = "text/javascript";
// 3.针对IE没有onload方法,他有自己的语法,script有一个状态码readyState刚开始存的是"loading",他会根据script标签加载的进度动态改变里面的值,加载完的话会改成"complete"或者"loaded"
// IE里面提供了一个事件onreadystatechange,当readyState发生改变的时候会触发这个事件
if(script.readyState){
script.onreadystatechange = function(){
if(script.readyState == "complete" || script.readyState == "loaded"){
callback(); //test();
}
}
}else{
script.onload = function(){ //2.所以采用script的onload方法让所有js加载完之后再来调用test,但是IE没有这个方法
callback(); //test();
}
}
script.src = url; //4.把url放到绑定事件之后,因为放前面如果网速特别快,会直接执行完这个不会触发onreadystatechange 事件
document.head.appendChild(script); //1.执行test函数如果text函数不修饰的话就会报错,因为
// 当执行document.head.appendChild(script)的时候上面的script.src是异步加载,所以执行完document.head.appendChild(script)的他可能还在加载所以就会报错
// 下载src他需要发一个请求,等请求完成之后开始回归资源的一个过程。因为是异步的,所以在发请求的时候他会执行下面,执行到test的时候他可能还没有加载完就会报错
}
loadScript('demo.js',test);//5.这样是不会运行的,因为他运行过程是先解析函数loadScript但是不会运行里面内容因为他只有loadScript('demo.js',test);执行之后才会才会加载函数里面的内容,所以没加载之前就调用test是找不到的
所以解决办法有三种
1.: loadScript('demo.js',function(){ //传一个匿名函数进去,相当于函数引用,在读的时候不会读里面的代码,在执行的时候才会读
test();
})
// 2.可以把函数里面的callback传一个字符串进去,然后利用eval(callback);他会把字符串当成函数代码来执行 loadScript('lesson3.js', "test()");-->传字符串进去
3.最好的最终的解决办法 在js外部函数里声明一个对象
var tools={
test : function(){
console.log(a);
},
demo : function(){
}
}然后直接把函数里面的调用函数的地方改成tools[callback]();然后就可以直接调用loadScript('demo.js',"test");
三,最终异步加载封装函数,loadScript();
function loadScript(url, callback) {
var script = document.createElement('script');
script.type = "text/javascript";
if (script.readyState) {
script.onreadystatechange = function() {
if (script.readyState == "complete" || script.readyState == "loaded") {
tools[callback]();
}
}
} else {
script.onload = function() {
tools[callback]();
}
}
script.src = url;
document.head.appendChild(script);
}
loadScript('lesson3.js', "test");
外部js代码,路径为lesson3.js
var tools = {
test: function() {
console.log('a');
}
}
四,异步js加载时间线
1.创建Document对象,开始解析web页面。解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中。这个阶段document.readyState = 'loading'。
2、遇到link外部css,创建线程加载,并继续解析文档。
3、遇到script外部js,并且没有设置async、defer,浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析文档。
4、遇到script外部js,并且设置有async、defer,浏览器创建线程加载,并继续解析文档。
对于async属性的脚本,脚本加载完成后立即执行。(异步禁止使用document.write())-->在异步或者采用onload方法的时候会使document.write()会消除文档流,他会把body里面的标签全部消除。
5、遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档。
=
6、当文档解析完成(dom树构建完成),document.readyState = 'interactive'。
7、文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意与async的不同,但同样禁止使用document.write());
8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
9、当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = 'complete',window对象触发load事件。
10.从此以异步响应方式,处理用户输入,网络事件等。
简单成三点
1.创建document对象
2.文档解析完了
3.文档解析完并加载完了,并且执行完了
8.附加
DOMCountentLoaded事件只能在addEventListener触发事件中触发,他会在文档解析之后触发,跟文档解析完成相当于并行触发
document.addEccentListener('DOMCountentLoaded',function(){console.log('a')},false);
采用这个方法可以把script写在body标签上面,因为他会在dom树解析完之后执行
文档解析完的意思就是dom树构建完成,但是没有执行,没有下载图片等东西