js函数相关

原文参考链接:http://javascript.ruanyifeng.com/grammar/function.html#toc1

1.1 函数名提升

javascript 引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。所以,下面的代码不会报错。


f();

function f() {}

表面上,上面代码好像在声明之前就调用了函数f。但是实际上,由于“变量提升”,函数f被提升到了代码头部,也就是在调用之前已经声明了。但是,如果采用赋值语句定义函数,JavaScript就会报错。

f();
var f = function (){};
// TypeError: undefined is not a function

//等同于

var f;
f();
f = function () {};
//调用f的时候,f只是被声明了,还没有被赋值,等于undefined,所以会报错

1.2 不能在条件语句中声明函数

根据ECMAScript的规范,不得在非函数的代码块中声明函数,最常见的情况就是if和try语句

if (foo) {
   function x() {}
}
try { 
  function x() {}
} catch(e) {
 console.log(e);
}

1.3 函数作用域#

作用域(scope)指的是变量存在的范围。Javascript只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。

注意,对于var命令来说,局部变量只能在函数内部声明,在其他区块中声明,一律都是全局变量。

if (true) { var x = 5;}
console.log(x); // 5
//虽然x在{}里面,但是,由于局部变量只存于函数内部。因此这里x依然是全局变量

1.4 函数内部变量的提升#

与全局作用域一样,函数作用域内部也会产生“变量提升”现象。var命令声明的变量,不管在什么位置,变量声明都会被提升到函数体的头部。

function foo(x) {
  if (x > 100) {
    var tmp = x - 100;
  }
}

//等同于

function foo(x) { 
   var tmp;
   if (x > 100) {
      tmp = x - 100;
   }
}


1.5 function的arguments对象转js数组#

var args = Array.prototype.slice.call(arguments);

//或者

var args = [];
for (var i = 0; i < arguments.length; i++) { 
  args.push(arguments[i]);
}


1.6 关于闭包#

闭包的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量始终保持在内存中。

function createIncrementor(start) {
 return function () {
           return start++; 
        };
}
var inc = createIncrementor(5);
  inc() // 5
  inc() // 6
  inc() // 7

//start是属于createIncrementor函数的局部变量。 每一次调用inc方法,都会使其自增。
//注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大 

1.7 js立即调用表达式#

目的

  1. 一是不必为函数命名,避免了污染全局变量;
  • 二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量
(function(){ /* code */ }());
// 或者
(function(){ /* code */ })();
//注意分号结尾

你可能感兴趣的:(js函数相关)