美文网首页
JavaScript(2)- Closures(闭包)and F

JavaScript(2)- Closures(闭包)and F

作者: sunboximeng | 来源:发表于2018-04-22 15:29 被阅读10次

Closures

如果把函数代码作为返回值,就会把函数代码的外部环境一并保存起来(close in),以便该函数在被调用时使用。Closure is the fundation for Ajax.

function makeMultiplier (multiplier) { 
 console.log("111");
 return (
  function (x) {
   console.log("222");
   return multiplier*x; 
  }
 );
}
makeMultiplier(2)
>>111
>>function (x) {
   console.log("222");
   return multiplier * x; 
  }

由于console.log("222")没有输出,说明该匿名函数没有被执行,而是把他的代码作为返回值。因此参数 multiplier 并没有得到赋值。 但是由于闭包机制的存在,即便代码没有执行,变量没有赋值,代码里面用到的外部的变量也会得到保存。

var a = makeMultiplier(2)
>>111
a(3)
>>222
>>6

作用域和命名空间

作用域

Javascript的变量范围是以函数为基础的,并不是每一对大括号都能拥有它自己的作用范围。

function test() { // 一个作用域
    for(var i = 0; i < 10; i++) { // 不是一个作用域
        
    }
    console.log(i); // 10
}

命名空间

当一个工程很大时,不用文件中的变量名、函数名和对象名,难免冲突。如果你在无意识的情况下重载了一个函数,Javascript根本不会提醒你。

HTML:

...
<head>
    <script src="js/script111.js"></script>
    <script src="js/script222.js"></script>
    <script src="js/scriptApp.js"></script>
</head>
...

script111.js

function say() {  return "My hobby is Popkart"; }

script222.js

function say() { return "My hobby is Reading books"; }

scriptApp.js

say();

输出My hobby is Reading books,因为script222.js中的say()函数把script111.js中的say()函数覆盖了。因此需要把各自的代码都放在自己的命名空间里。虽然JavaScript并没有命名空间这一概念,但这种功能非常容易实现。

方法一:把代码封装在不重名的对象里。
script111.js

var fooSpace = {};
fooSpace.hobby = "Popkart";
foospace.say = function() { 
  return "My hobby is " + fooSpace.hobby;
}

script222.js

var barSpace = {};
barSpace.hobby = "Reading books";
barspace.say = function() { 
  return "My hobby is " + fooSpace.hobby;
}

scriptApp.js

fooSpace.say();

输出My hobby is Popkart。这虽然减少了全局变量的个数,但是对象的属性(如 hobby)完全暴露在外面,外部很容易改变内部的状态。

方法二:Immediately-Invoked Function Expression
对象 + 函数 --> 选择性的暴露对象的属性

script111.js

(function (window) {
  var fooSpace = {};
  // 由于hobby变量在函数里面,也就不会和下面那个函数里的hobby变量冲突
  // 因为函数拥有自己独立的作用域
  var hobby = "Popkart";
  // 只把say方法暴露出去
  fooSpace.say = function () {
    return "My hobby is " + hobby;
  }
  // 把fooSpace暴露在全局作用域
  window.foo = fooSpace;
})(window);

script222.js

(function (window) {
  var barSpace = {};
  var hobby = "Reading books";
  barSpace.say = function () {
    return "My hobby is " + hobby;
  }
  window.bar = barSpace;
})(window);

scriptApp.js

foo.say();
bar.say();
bar.hobby // undefined。 hobby相当于是私有变量了,全局作用域无法访问它的值。

相关文章

网友评论

      本文标题:JavaScript(2)- Closures(闭包)and F

      本文链接:https://www.haomeiwen.com/subject/temqlftx.html