Skip to content

全局对象

无论是浏览器环境,还是node环境,都会提供一个全局对象

  • 浏览器环境:window
  • node环境:global

全局对象有下面几个特点:

  • 全局对象的属性可以被直接访问
js
console.log();
  • 给未声明的变量赋值,实际就是给全局对象的属性赋值

    永远别这么干

    js
    a=1;
    console.log(window.a)//实际上挂载到window上去了
  • 所有的全局变量、全局函数都会附加到全局对象

    这称之为全局污染,又称之为全局暴露,或简称污染、暴露

    如果要避免污染,需要使用立即执行函数改变其作用域

    立即执行函数又称之为IIFE,它的全称是Immediately Invoked Function Expression

    IIFE通常用于强行改变作用域

    js
    function add (){	)//实际上挂载到window上去了
        //xxx
    }

    全局污染

    实际上我们开发可能会遇到不同人负责不同的js文件,假入小郑负责a.js,我负责b.js

    js
    //a.js
    const a = 10;

    这个时候我想要在b.js中也定义一个a变量,但是小郑已经定义过了,这样就造成了冲突。

    可以通过立即执行函数来解决

    js
    (function(){
        var a=20;
        a++;
        
        function add () {}
    })()
    //这样立即执行函数就形成了自己的作用域不会与外界产生冲突,也不会将变量挂载到window上,避免了全局污染。

    但是,我又想将我b.js中一些东西,比如add()暴露出去怎么办呢?

js
var zy = (function(){
    var a=20;
    a++;
    
    function add () {}
    
    return {
        add:add//可以使用返回值的形式,然后使用一个变量接收
    }
})()

//这样,小郑在使用我的b.js时,直接可以
zy.add()进行不同文件之间的调用了

练习

  1. 避免全局污染
js
var a = 1; // 避免污染
var b = 2; // 避免污染
// 暴露为:sayHi
function hello() {
  console.log('hello world');
}
// 暴露为:count
var count = 1;

答案:

js

var zy = (function () {
  var a = 1; // 避免污染
  var b = 2; // 避免污染
  // 暴露为:sayHi
  function hello() {
    console.log('hello world');
  }
  // 暴露为:count
  var count = 1;

  return {
    sayHi: hello,
    count: count
  }
})()

使用 1.js 暴露的函数和变量

js
var a = 3; // 避免污染
var b = 4; // 避免污染

console.log(zy.count);
console.log(zy.hello());

MIT License