首页 > 代码库 > 一些core javascript的基础知识

一些core javascript的基础知识

一、setTimeout  

setTimtout(function(){   alert(2);                           // 后弹出},0);alert(1);                              // 先弹出

 

  对于如上代码,包含原理如下:

  1、首先jsvm只会执行一个线程;

  2、当这个线程遇到setTimout的时候,就会讲这个function放到某个队列里面;

  3、当前这个线程空闲的时候,就会执行任务队列轮询的代码,将满足条件的函数拿出来执行。

  比较简单典型的一个应用场景就是:

$(elem).html(xxxxxx);setTimeout(function() {  // 内部DOM操作很复杂,此处setTimeout用于保证在内部DOM操作结束并且相关内存被释放掉后执行后续代码}, 0);

二、eval

  js中除了全局作用域和函数作用域之外,还存在一个eval作用域。

  eval函数执行的时候,会根据当前执行上下文创建一个作用域。

  此处有如下代码:

function a() {  var b = new SomeThing();  return function() {    eval(‘‘);  };}

 

  如果内部的那个匿名函数使用eval,即便eval中执行的代码没有用到b变量,b也不会被释放掉;如果没有使用eval函数,有的浏览器会释放掉b,有的会根据自身优化,选择不释放掉b。

  所以,eval通常是不应该非全局作用域下面执行的,于是jquery有了globalEval函数。

三、预编译

  先分别上如下几个片段的代码:

<html><head><script>a();function a(){  alert(1);}</script></head><body></body></html>

 

<html><head><script>a();</script><script>function a(){  alert(1);}</script></head><body></body></html>
<html><head><script>a();var b = function a(){  alert(1);}</script></head><body></body></html>

  执行结果分别是:

  第一段代码:弹出1;

  第二段代码:第一个script片段报错,a不存在;

  第三段代码:报错,a不存在;

  原因:

  第一段代码中,jsvm会预编译,构造好a函数,所以访问a函数的顺序是不重要的;

  第二段代码中,预编译是会分代码块执行的,每个script都会形成一个代码块,即便script是通过src引入js的;

  第三段代码中,a函数的定义由于放在了一个表达式当中,因此jsvm不会预编译。

  但是,此处还可以继续深入,第三段代码改成如下所示:

<html><head><script>var b = function a(){  alert(1);}a();</script></head><body></body></html>

 

  这段代码也同样会报错,a不存在。为什么呢?原因就是a函数放在了表达式当中,jsvm会把a函数看作一个匿名函数,因此在当前语句执行完,a就被释放掉了。

  但是,请注意,上面讨论的都是根据w3c标准得出的结果,在第三段和第四段代码中,IE 6、7、8还是会预编译的,并且不会释放掉a,因此不会报错。

四、自执行函数

  自执行函数的几种形式:  

(function() {})();(function() {}());!function(){}();void function(){}();

 

  其中第三种写法会造成额外的运算,因为要对返回的内容做“非”操作。

五、弱式转化[TODO]

六、预编译中的变量声明

  如下代码:  

function a(x){  return x*2;}var a;alert(a);

 

  var a只是声明,并不会干啥,var a只会让当前作用域的alert(a)不会报a不存在的错误,a实际上是什么,需要显示赋值;如果var a之前已经存在a了,则啥也不干。

七、function传参

  如下代码:

function fn1(a, b, c){   a = 1.2;   b = 2.2;   c.c = 3.2;}var a = 1;var b = 2;var c = {c:3};fn1(a,b,c);alert(a);alert(b);alert(c.c);

 

  原理不难理解,注意值类型和引用类型的区别。

八、作用域链

  有如下几点:

  1、作用域链是在定义的时候就确定下来了的;

  2、隐式对象模型:对于一个作用域,jsvm会创建一个隐式对象,然后在这个对象上面绑定当前作用域的各种变量。多个函数的嵌套定义也就会形成一条作用域链了。如果在某个作用域中要访问一个a变量,则会首先在当前作用域中查找是否存在a变量,如果不存在,则向上找父作用域隐式对象中是否存在a变量,依次类推,如果到了根作用域还找不到a变量的话,就会报错了。

九、类数组结构

  第一个问题,如何构造类数组结构?思路简单,不赘述。

  jquery选择器构造出来的就是一个类数组结构。

十、工厂模式

function factory() {  return new ThisIsAClass();}

 

  优点:

  1、可以防止调用者把构造函数直接当成函数调用了;

  2、省略了成片成片的new关键字,jquery就是一个正面例子。

 

一些core javascript的基础知识