Maison  >  Article  >  interface Web  >  Exemples qui vous apprennent à écrire du code JavaScript plus stable et plus lisible

Exemples qui vous apprennent à écrire du code JavaScript plus stable et plus lisible

黄舟
黄舟original
2017-03-15 14:59:021237parcourir

Chacun a son propre style de programmation , et il est inévitable de ressentir les styles de programmation des autres - de modifier le code des autres. "Modifier le code des autres" est une chose très douloureuse pour nous. Parce que certains codes ne sont pas si faciles à lire et à maintenir, laisser une autre personne modifier le code d'une autre personne peut finir par modifier une variable et ajuster le timing d'appel d'une fonction Mais cela prend. une heure ou plus pour lire et clarifier le code des autres. Cet article vous guidera étape par étape pour reconstruire un "composant" qui obtient la position - améliorant la lisibilité et la stabilité de votre code javascript.

Le contenu de cet article est le suivant :

  • Séparez votre code javascript

  • Les fonctions ne doivent pas s'appuyer trop sur l'environnement externe

  • Sémantiqueet réutilisation

  • Les composants doivent se concentrer sur la logique, le comportementjuste l'encapsulation

  • Formez votre propre style de code

Séparez votre code javascript

La pièce suivante de code démontre la difficulté de lecture/ Code modifié :

(function (window, namespace) {
    var $ = window.jQuery;
    window[namespace] = function (targetId, textId) {
        //一个尝试复用的获取位置的"组件"
        var $target = $('#' + targetId),//按钮
            $text = $('#' + textId);//显示文本
        $target.on('click', function () {
            $text.html('获取中');
            var data = '北京市';//balabala很多逻辑,伪代码,获取得到位置中
            if (data) {
                $text.html(data);
            } else
                $text.html('获取失败');
        });
    }
})(window, 'linkFly');

Ce morceau de code, nous acceptons temporairement qu'il constitue un "composant".
Le code ci-dessus est un moyen typique de tout faire. Une fois la logique interne remplie, cela deviendra ingérable. Et une fois la demande augmentée, par exemple, le format de données renvoyé par l'obtention de l'emplacement doit être traité. , il faut alors entrer à l'intérieur et le chercher. Le code qui traite les données est alors modifié.

On sépare la logique et obtenons le code comme suit :

(function (window, namespace) {
    var $ = window.jQuery,
        $target,
        $text,
        states= ['获取中', '获取失败'];
    function done(address) {//获取位置成功
        $text.html(address);
    }
    function fail() {
        $text.html(states[1]);
    }
    function checkData(data) {
        //检查位置信息是否正确
        return !!data;
    }
    function loadPosition() {
        var data = '北京市';//获取位置中
        if (checkData(data)) {
            done(data);
        } else
            fail();
    }
    var init = function () {
        $target.on('click', function () {
            $text.html(states[0]);
            loadPosition();
        });
    };
    window[namespace] = function (targetId, textId) {
        $target = $('#' + targetId);
        $text = $('#' + textId);
        initData();
        setData();
    }
})(window, 'linkFly');

La fonction ne doit pas trop s'appuyer sur l'environnement externe

Dans le code ci-dessus, on a Si nous coupons l'ensemble du composant en diverses fonctions (notez que je parle de fonctions, pas de méthodes), un nouveau problème surgit souvent ici : les fonctions s'appuient trop sur des variables incontrôlables.

Les variables $target et $text sont des variables globales dans l'environnement et se voient attribuer des valeurs lorsque le composant est initialisé. La plupart des méthodes de fonctionnement de notre code coupé reposent sur $text, en particulier $text et done. () , fail(), une fois la structure et la logique liées à $text modifiées, notre code subira des changements considérables.

Les éléments liés à la page/DOM ne sont pas dignes de confiance (comme $target et $text). Une fois la structure de la page modifiée, son comportement changera également dans une large mesure. Et les fonctions ne doivent pas dépendre de l’environnement extérieur.
Concernant les variables incontrôlables, nous devrions démêler la relation entre les fonctions et les variables dépendantes, afin que la fonction puisse se concentrer davantage sur la logique de son propre domaine et devenir plus pure. Pour faire simple : toutes les variables externes dont dépend la fonction doivent être transmises à la fonction via des paramètres.
Le nouveau code est le suivant :

(function (window, namespace) {
    var $ = window.jQuery;
    //检查位置信息是否正确
    function checkData(data) {
        return !!data;
    }
    //获取位置中
    function loadPosition(done, fail) {
        var data = '北京市';//获取位置中
        if (checkData(data)) {
            done(data);
        } else
            fail();
    }
    window[namespace] = function (targetId, textId) {
       var  $target = $('#' + targetId),
            $text = $('#' + textId);
        var states = ['获取中', '获取失败'];
        $target.on('click', function () {
            $text.html(states[0]);
            loadPosition(function (address) {//获取位置成功
                $text.html(address);
            }, function () {//获取位置失败
                $text.html(states[1]);
            });
        });
    }
})(window, 'linkFly');

Sémanticisation et réutilisation

La variable states est un tableau, le comportement qu'elle décrit est difficile à lire, chaque fois que vous le regardez. En ce qui concerne les états [0], j'ai envie de tuer l'auteur original chaque minute, car nous devons toujours nous souvenir de la valeur des états variables dans le code, nous devrions rendre les choses aussi simples. à lire le plus possible.

De plus, $text.html dans le code ci-dessus est une duplication de code typique. Nous modifions à nouveau le code. Veuillez faire attention à la position du code de changeStateText() que nous avons extraite dans le code modifié cette fois. Il n'a pas été promu dans l'environnement supérieur (c'est-à-dire l'ensemble du grand fermeture environnement).

(function (window, namespace) {
    var $ = window.jQuery;
    function checkData(data) {
        return !!data;
    }
    function loadPosition(done, fail) {
        var data = '北京市';//获取位置中
        if (checkData(data)) {
            done(data);
        } else
            fail();
    }
    window[namespace] = function (targetId, textId) {
        var $target = $('#' + targetId),
            $text = $('#' + textId),
            changeEnum = { LOADING: '获取中', FAIL: '获取失败' },
            changeStateText = function (text) {
                $text.html(text);
            };
        $target.on('click', function () {
            changeStateText(changeEnum.LOADING);
            loadPosition(function (address) {
                changeStateText(address);
            }, function () {
                changeStateText(changeEnum.FAIL);
            });
        });
    }
})(window, 'linkFly');

En matière de sémantique, nous devons connaître la logique et la sémantique de l'ensemble du code actuel :

Dans l'ensemble de ce composant, tous les modules de fonction peuvent être divisés en : outils et outils à condition qui.

L'environnement de niveau supérieur (l'ensemble de la grande fermeture) joue le rôle d'un outil dans notre métier. Sa tâche est de créer un ensemble d'outils liés à l'obtention de la logique de localisation, et dans la fenêtre[espace de noms]) function , est l’identité du fournisseur de l’outil. C’est la seule entrée et est responsable de fournir l’activité complète du composant aux utilisateurs de l’outil.
Le $text.html() ici n'appartient pas logiquement à l'outil, mais appartient aux commentaires obtenus par le fournisseur d'outils après avoir utilisé l'outil, donc la fonction changeStateText() est placée dans la fenêtre du fournisseur d'outils[espace de noms] () .

组件应该关注逻辑,行为只是封装

到此为止,我们分离了函数,并让这个组件拥有了良好的语义。但这时候来了新的需求:当没有获取到位置的时候,需要进行一些其他的操作。这时候会发现,我们需要window[namespace]()上加上新的参数。
当我们加上新的参数之后,又被告知新的需求:当获取位置失败了之后,需要修改一些信息,然后再次尝试获取位置信息。
不过幸好,我们的代码已经把大部分的逻辑抽离到了工具提供者中了,对整个工具的逻辑影响并不大。
同时我们再看看代码就会发现我们的组件除了工具提供者之外,没有方法(依赖在对象上的函数)。也就是说,我们的组件并没有对象。

我见过很多人的代码总是喜欢打造工具提供者,而忽略了工具的本质。迎合上面的增加的需求,那么我们的工具提供者将会变得越来越重,这时候我们应该思考到:是不是应该把工具提供出去?

让我们回到最初的需求——仅仅只是一个获取位置的组件,没错,它的核心业务就是获取位置——它不应该被组件化。它的本质应该是个工具对象,而不应该和页面相关,我们从一开始就不应该关注页面上的变化,让我们重构代码如下:

(function (window, namespace) {
    var Gps = {
        load: function (fone, fail) {
            var data = '北京市';//获取位置伪代码
            this.check(data) ?
                done(data, Gps.state.OK) :
                fail(Gps.state.FAIL);
        },
        check: function (data) {
            return !!data;
        },
        state: { OK: 1, FAIL: 0 }
    };
    window[namespace] = Gps;
})(window, 'Gps');

在这里,我们直接捏死了工具提供者,我们直接将工具提供给外面的工具使用者,让工具使用者直接使用我们的工具,这里的代码无关状态、无关页面。

至此,重构完成。

形成自己风格的代码

之所以讲这个是因为大家都有自己的编程风格。有些人的编程风格就是开篇那种代码的…
我觉得形成自己的编程风格,是建立在良好代码的和结构/语义上的。否则只会让你的代码变得越来越难读,越来越难写。
****
单var和多var
我个人是喜欢单var风格的,不过我觉得代码还是尽可能在使用某一方法/函数使用前进行var,有时候甚至于为了单var而变得丧心病狂:由于我又过分的喜爱函数表达式声明,函数表达式声明并不会在var语句中执行,于是偶尔会出现这种边声明边执行的代码,为了不教坏小朋友就不贴代码了(我不会告诉你们其实是我找不到了)。

对象属性的屏蔽
下面的代码演示了两种对象的构建,后一种通过闭包把内部属性隐藏,同样,两种方法都实现了无new化,我个人…是不喜欢看见很多this的..但还是推荐前者。

(function () {
    //第一种,曝露了_name属性
    var Demo = function () {
        if (!(this instanceof Demo))
            return new Demo();
        this._name = 'linkFly';
    };
    Demo.prototype.getName = function () {
        return this._name;
    }

    //第二种,多一层闭包意味内存消耗更大,但是屏蔽了_name属性
    var Demo = function () {
        var name = 'linkFly';
        return {
            getName: function () {
                return name;
            }
        }
    }
});

巧用变量置顶[hoisting]
巧用函数声明的变量置顶特性意味着处女座心态的你放弃单var,但却可以让你的函数在代码结构上十分清晰,例如下面的代码:

(function () {
    var names = [];
    return function (name) {
        addName(name);
    }
    function addName(name) {
        if (!~names.indexOf(name))//如果存在则不添加
            names.push(name);
        console.log(names);// ["linkFly"]
    }
}())('linkFly');

if和&&
这种代码,在几个群里都见过讨论:

(function () {
    var key = 'linkFly',
        cache = { 'linkFly': 'http://www.cnblogs.com/silin6/' },
        value;
    //&&到底
    key && cache && cache[key] && (value = cache[key]);
    //来个if
    if (key && cache && cache[key])
        value = cache[key];
})();

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn