누구나 자신만의 프로그래밍 스타일이 있으며, 다른 사람의 프로그래밍 스타일을 느끼는 것은 불가피합니다. 즉, 다른 사람의 코드를 수정하는 것입니다. "다른 사람의 코드를 수정하는 것"은 우리에게 있어서 매우 고통스러운 일입니다. 일부 코드는 읽고 유지하기가 쉽지 않기 때문에 다른 사람이 다른 사람의 코드를 수정하도록 허용하면 결국 변수 를 수정하고 함수 의 호출 타이밍을 조정하는 결과를 가져올 수 있습니다. 다른 사람의 코드를 읽고 명확하게 만드는 데 한 시간 이상 걸립니다. 이 글에서는 위치를 획득하는 "구성 요소"를 재구성하는 방법을 단계별로 안내하여 javascript 코드의 가독성과 안정성을 향상시킵니다.
자바스크립트 코드 분리다음 부분 코드 읽기의 어려움을 보여줌/수정된 코드:이 글의 내용은 다음과 같습니다.
(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');
위의 코드는 모든 작업을 수행하는 일반적인 방법입니다. 일단 내부 로직이 채워지면 생활이 불가능해집니다. 그리고 수요가 증가하면 예를 들어 위치를 가져와서 반환된 데이터 형식을 처리해야 합니다. 그러면 안으로 들어가서 데이터를 처리하는 코드가 수정됩니다.
(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');
제어할 수 없는 변수에 대해서는 함수와 종속변수의 관계를 풀어서 함수가 자신의 영역의 논리에 더욱 집중하고 순수해질 수 있도록 해야 합니다. 간단히 말하면, 함수가 의존하는 모든 외부 변수는 매개변수를 통해 함수에 전달되어야 합니다.
새 코드는 다음과 같습니다.
(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');
폐쇄 전체의 환경)으로 승격되었습니다.
(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');
여기서 $text.html()은 논리적으로 도구에 속하지 않고 도구 사용 후 도구 제공자가 얻은 피드백에 속하므로 ChangeStateText() 함수는 도구 제공자 창[네임스페이스]에 배치됩니다. () .
到此为止,我们分离了函数,并让这个组件拥有了良好的语义。但这时候来了新的需求:当没有获取到位置的时候,需要进行一些其他的操作。这时候会发现,我们需要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]; })();
위 내용은 보다 안정적이고 읽기 쉬운 JavaScript 코드를 작성하는 방법을 알려주는 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!