函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。为了实现这种词法作用域,JavaScript函数对象的内部状态不仅包含函数的逻辑代码,还必须引用当前的作用域链。函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数的作用域内,这种特性其实就是“闭包”。
继续来看代码吧:
function counter(){ var num = 0; return { count : function(){ return num++; }, reset : function(){ return num = 0; } } }; var firstNum = counter(); var secondNum = counter(); console.log(firstNum.count()); // 0 console.log(secondNum.count()); // 0 firstNum.reset(); console.log(firstNum.count()); // 0 num已被重置,所以返回的为0 console.log(secondNum.count()); // 1 num未被重置,所以返回的是1 console.log(firstNum,secondNum); // 都为 Object{ count:function(),reset:function(),__proto__} 并且并不能在其中找到counter里var的n,这也实现了函数里的私有变量,只将需要暴露的两个方法给暴露在外。
闭包用的多的两个作用:读取函数内部的变量值;让这些变量值始终保存着(在内存中)。
同时需要注意的是:闭包慎用,不滥用,不乱用,由于函数内部的变量都被保存在内存中,会导致内存消耗大。
JavaScript中的this
在JavaScript中,this通常指向的是我们正在执行的函数本身,或者是,指向该函数所属的对象。
全局的this → 指向的是Window
函数中的this → 指向的是函数所在的对象
对象中的this → 指向其本身
验证代码:
console.log(this); // Window {external: Object, chrome: Object, document: document, global: Window, cr: Object…} 全局下执行console.log,所以此处指向的是Window ~function seeThis(){ console.log(this); // Window {external: Object, chrome: Object, document: document, global: Window, cr: Object…} 由于我是在全局下写的这个函数,所以此处指向的还是Window }(); var obj = { name:"野兽", showThis:function(){ console.log(this); // Object {name: "野兽",showThis:function(),__proto__} 此处打印的是对象本身 } }; obj.showThis();
arguments
在Javascript函数体内,arguments像数组一样(并不是真的数组),有length属性,可以代表传给函数的参数的个数。
简单来说,arguments函数执行时所传的实际参数。
比如:arguments[0]表示传入第一个参数。
用代码验证:
function argumentsTest(){ console.log(arguments[0]?arguments[0]:"Hello World",arguments[1]?arguments[1]:"你好 世界") }; argumentsTest(); // Hello World 你好 世界 argumentsTest("This is firstValue => arguments[0].","This is secondValue => arguments[1]."); // This is firstValue => arguments[0]. This is secondValue => arguments[1].