一些core javascript的基础知识

一、setTimeout

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

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

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

$(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>
<!-- 第三段代码结束 -->

执行结果分别是:

原因:

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

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

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

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

四、自执行函数

自执行函数的几种形式:

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

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

五、数据类型转换

参考:JavaScript中,{}+{}等于多少?

六、预编译中的变量声明

如下代码:

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);

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

八、作用域链

有如下几点:

九、类数组结构

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

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

十、工厂模式

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

优点:

blog comments powered by Disqus