Javascript编程习惯总结

1. 团队合作------如何避免 JS 冲突

我们进入公司之后,我们可能会从新开发一个网站.这种情况,我们定义什么参数,使用什么名字全部都是随自己的想法,自己维护也可能会很正常.

但是假如我们进入公司接手的是别人的代码呢?和其他同事一起同事合作开发呢?

这时候我们很多之前不注意的小习惯就可能会造成巨大的灾难.

    <script type="text/javascript">
        var a = "li";
        var b = "peng";
        ...
    </script>

可以看到,我们在编写 JS 的时候直接定义了两个变量,他们的作用域都是直接在 Window 作用域下的,但是假如我们的另外一个工程师,也去直接定义了两个变量,而且名字相同呢?

这样会直接造成代码的冲突,引起某些不知名的错误.

那我们该如何去解决呢?

我们可以使用匿名函数去对脚本进行包裹,让变量的作用域控制于匿名函数中.

    <script type="text/javascript">
        (function(){
            var a = "li";
            var b = "peng";
            ...
        })();
    </script>   

可以看见,我们在上的代码中使用了一个匿名函数 (function(){})();.

执行代码的时候,包裹在这个匿名函数中的变量,它的作用域就不是 window 了,而是局限在函数内部,这样也就不会引起代码冲突了.

但是这样并不是就一劳永逸了,假如说我们在不同的脚本之间互相通信呢?

我们需要在网页中添加新功能,在新功能中需要使用到之前定义的函数中的某一个变量,这时候该怎么办?

最简单的解决方案:直接把新的代码也放在之前的匿名函数中,但是,这样并不符合我们的代码规范,

而且加入之前的功能是已经离职的员工写的呢?

你还需要首先去阅读他之前写的程序,去避开每一个冲突.

其次,你还需要将自己书写的内容去进行封装,这样会逼死人的

(PS: 别问我我是怎么知道的 ╮(;´༎ຶД༎ຶ`)╭ )

那么如何去解决这个问题呢?

我们可以在 window 作用域下定义一个全局变量,把它作为一个桥梁,完成各匿名函数之间的通信.

    <script type="text/javascript">
        var str;
    </script>
    <script type="text/javascript">
        (function(){
            var a = "li";
            str = b = "peng";
            ...
        })();
    </script>   
    <script type="text/javascript">
        (function(){
            var a = "li";
            var b = str;
            ...
        })();
    </script>   

但是我们有多个变量呢?难道需要一个个去定义么?

我们可以使用一个 { } 对象类型的变量作为全局变量,如果匿名函数之间需要多个变量作为通信桥梁,可以将这些变量都作为全局变量的属性,这样可以保证全局变量很少,而且拓展性很好.

    <script type="text/javascript">
        var GLOBAL = {};
    </script>
    <script type="text/javascript">
        (function(){
            var a = "li";
            var b = "peng";
            GLOBAL.str = a;
            GLOBAL.str2 = b;
            ...
        })();
    </script>   
    <script type="text/javascript">
        (function(){
            var a = GLOBAL.str;
            var b = GLOBAL.str2;
            ...
        })();
    </script>

除此之外,我们在团队合作中,还可以将自己的名字缩写也放在变量命名中,而且还应该去适当的写明注释,这些都是可以大大加快团队合作进程的工作方式.


2 给程序一个统一的入口 ------ window.onload 和 DOMReady

大家都知道,JS 是中脚本语言,我们的浏览器下载到哪里,就会执行到哪里.

这种特性会为编程带来很大的便利,但是同时也会造成代码过于零散,四处分布.

为了解决这种问题,我们首先需要从功能上对程序进行职能的划分.

网页中的 JS 从功能上应该分为两大部分 ------ 框架部分应用部分.

1. 框架部分提供对 JS 代码的组织作用的代码,其中应该包括 定义全局变量, 定义命名空间等方法.它和应用无关,每个页面都需要包括相同的框架,所以框架部分的代码在每个页面都相同.

2. 应用部分提供的是页面功能逻辑,不同页面会有不同的功能,不同的页面应用部分的代码也不相同.

    <script type="text/javascript">
        function init(){
        
            (function(){
                ...
            }());
            
            (function(){
                ...
            }());
            
            (function(){
                ...
            }());
            
            (function(){
                ...
            }());
        }
    </script>

可以看见,我们将所有应用部分的代码都集中到 init 函数内了,所有的初始化工作都在这里,这里就是网页程序的入口.

但是需要注意,如果程序控制某个 DOM 节点,而该 DOM 节点当时还没有被载入,程序会直接报错.

有两种解决方案,第一种最简单的解决方案,直接把脚本放在后面.

但是有时候,我们希望我们的程序能够无视这种放置规则,可以让程序的位置在 DOM 节点之前或者之后.

这时候我们可以去 监听 window 对象的 onload 事件,当 window 触发 onload 事件之后去调用脚本.

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript">
        function init(){
            alert(document.getElementById("test").innerHTML);
        }
        window.onload = init;
    </script>
</head>
<body>
    <div class="test">MR_LP</div>
</body>
</html>

这样,我们的脚本不会立即执行,而是在 window.onload 之后才去执行.

而 window 对象会在页面内元素全部加载完成之后才去触发 onload 事件,而这时候我们的 test 已经加载完毕,所以并不会报错.

你以为现在就可以万事大吉了么? 当然不是. ٩(๑˃̌ۿ˂̌๑)۶

如果页面加载的时候,存在某张超级大的图片呢?

window.onload 会等全部加载完成才会触发,难度这期间就让用户等着?

这时候就要说到 DOMReady 了.

DOMReady 只判断页面内所有的 DOM 节点 是否已经全部生成,至于节点中的内容是否已经加载,并不会检查.

所以 DOMReady 会 比 window.onload 加载速度要快很多.

但是需要注意, DOMReady 并不是原生 JS 支持的事件,一般我们都是结合 JS 框架去使用.

如 jQuery

<!DOCTYPE html>
<html >
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" scr="http://ajax.googleAPIs.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
    <script type="text/javascript">
        function() init{
            alert(document.getElementById("test").innerHTML);
        }
        $(document).ready(init);
    </script>
</head>
<body>
    <div class="test">MR_LP</div>
</body>
</html>

当然我们也可以自己去模拟 DOMReady ,即我们去定义了 init 函数,之后等<body>之前的时候去调用一下 init 函数,这时候虽然 DOM 节点不一定都全部加载完成了,但是却一定都生成了,通过这种方式,可以去简单模拟一下 DOMReady.

完事了? 当然没有 (இдஇ) .

在实际工作中,网站的头部和尾部经常会做成独立的文件,用服务器端语言 include 到网页中,所以我们的网页经常会拆散成三个文件,头部,主体和尾部三个文件.

一般来说,头尾文件都非常稳定.因为全站公用的统一结尾,这部分不会经常修改,而主体部分是每个页面各不相同的,如果有的页面不需要 JS, 这时候我们的主体中可能就没有 init 函数了,这时候调用就肯定会报错了.

这时我们当然可以去做一个规范,让每个页面都去书写一次,但是这并不合理.

正确的处理方式是我们在书写 init 之前可以先去判断一下 init 是否存在.

    if(init){
        init();
    }

这样就可以有效的避免上述问题了.


作者:MR_LP___李鹏
链接:https://www.jianshu.com/p/92a41e9b4a1b
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。