Javascript应用-Js在页面中被引入的几种方法
javaScript是一种解释型语言,它的执行是自上而下,但是各个浏览器对于至上而下的理解是有细微差别的,而代码的上下游也就是程序流又对于程序正确至关重要。
首先得了解有几种方法能把javaScript加入到页面中? 常见下述的前2种,其实还有更多。
1.页面中直接引入外部js文件:<script src=\”my.js\”></script>
2.页面中直接写入 js片段: <script>alert(1)</script>
3.在js中引入js文件(比较少用): document.write(\”<scr\”+\”ipt src=\’my.js\’></scr\”+\”ipt>\”);
注意:这时候\”..</script>\”必须拆成\”</scr\”+\”ipt>\”,否则浏览器可能会把父js片段关闭掉,出错;
4.同样在js中引用其他js片段,document.write(\”<scr\”+\”ipt>alert(1)</scr\”+\”ipt>\”);
你可能觉得这个并没有必要,既然已经在script中了还套一层干嘛?呵呵,怎么说也是一种写法,而且它具有其特殊的行为,稍后我们讨论到。
5.使用Ajax中的xmlHttpRequest结合eval()来引入js,我最早在Dojo的代码见到,写的详细些:
var ajaxRequest = getXmlHttpRequest()//省去各个浏览器得到xmlHttpRequest的部门
ajaxRequest.open(\”GET\”,\”my.js\”,false);//使用xmlHttpRequest对象Get方法的同步调用
ajaxRequest.send(null);
sJsFragment = ajax.responseText;//得到字符串为js片段
eval(sJsFragment);//执行js片段
注意:这里要求my.js即后来的sJsFragment内容得是非常规范的js,且没有//开头的注释,怎样检查js是否规范呢?去http://jslint.com/
6.无所不能的Dom方法,非常好用:
var oScript = document.createElement(\”script\”);//创建一个Script元素
oScript.src = \”my.js\”;//制定src属性
document.getElementsByTagName(\”head\”)[0].appendChild(oScript);
说明:my.js的内容会在oScript加入到文档中之后获得并执行。仔细看下这段容易发现这个调用是异步的,可以在文档载入之后通过事件触发,我用它变通了一下,作为了xmlHttpRequest的Get方法在跨域取数时的替代,获得了很完美的效果,以后有机会专门写篇文。
六种不少吧,可能还会有吧,而且这几种之间还可能相互嵌套,变化无常。
其中1、2、4、6种方式引入的javaScript的执行顺序是非常自然的,随着页面的载入以及后续的事件触发,它们遵守先来后到、而其内部自上而下。
JavaScript为什么是单线程的,js执行顺序
什么是进程和线程
进程:进程其实是一种比较抽象的概念,你可以理解为系统进行资源分配和调度的一个独立单位。(每次打开软件就执行一个或多个进程,进程是程序的最小执行单位,执行过程)
线程:早期的操作系统中并没有线程的概念,后来随着计算机发展,线程间的的切换开销较大,对于复杂的程序的要求已经难以满足。线程因此而出现(线程的调度和切换比进程快得多),线程是建立在进程的基础上程序执行流的最小单元,一个进程可以有多个线程一个进程中只有一个执行流称作单线程。
下图中,看到一个应用程序包含的线程数,每个名称都是一个进程,每个进程有多个线程。
JS为什么是单线程
多线程拥有更高的效率,那为什么js不采用多线程呢?其实这与他的主要作用有关,js用来使网页具有动态交互的功能,便于网站的与用户间的沟通,以及操作dom。如果你有多个线程来同时操作一个dom结点,浏览器无法确认应该以哪些为准,可能出现无法预知的错误。
js执行顺序
1.单线程是自上而下按照顺序执行的吗?
答案是不一定,如果全部都是同步任务,那么会自上而下前一个任务执行完毕,后一个任务才会执行。
2.同步任务和异步任务
同步任务是指主线程上排队执行的任务,任务一个接一个执行。
异步任务是指不进入主线程,而进入任务队列的任务(如回调函数,定时器,事件响应等),只有当主线程上的所有同步任务执行完毕后,主线程才会读取任务队列,开始执行异步任务。
可大致理解问:
- 当代码开始执行时,所有的代码都被放到执行栈中执行;
- 执行过程中遇到异步函数将回调函数添加到一个任务队列里面;然后继续走下面的代码;
- 当执行栈中的代码执行完以后,会去循环任务队列里的函数(异步);
- 将任务队列里的函数放到执行栈中执行;
- 循环往复知道全部执行完毕;
知道基本的规则还不够,因为异步任务又可分为微任务和宏任务,也有相关的执行顺序。(微任务和宏任务可以理解为不同类型的异步任务执行顺序的两种)
- 宏任务:包括整体代码script,setTimeout,setInterval、setImmediate。
- 微任务:原生Promise(有些实现的promise将then方法放到了宏任务中)、process.nextTick、Object.observe(已废弃)、 MutationObserver
我们需要知道代码执行由<script/>宏任务开始的,在执行中微任务是快于宏任务的。
所以异步任务的执行顺序如下:
- 优先执行微任务队列中的任务
- 微任务执行完后去执行第一个宏任务
- 在执行任何一个宏任务之后都会先查看微任务队列中是否有任务需要执行,有的话再次先执行所有的微任务; 如果没有,则执行下一个宏任务(重复执行此部分操作)。
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。