วิธีที่ดีที่สุดในการจัดระเบียบโค้ด jQuery / JavaScript (2013) [ปิด]


104

ปัญหา

คำตอบนี้ได้รับคำตอบมาก่อน แต่เก่าและไม่ทันสมัย ฉันมีโค้ดมากกว่า 2,000 บรรทัดในไฟล์เดียวและอย่างที่เราทราบกันดีว่านี่เป็นการปฏิบัติที่ไม่ดีโดยเฉพาะอย่างยิ่งเมื่อฉันกำลังมองหาโค้ดหรือเพิ่มคุณสมบัติใหม่ ๆ ฉันต้องการจัดระเบียบรหัสของฉันให้ดีขึ้นทั้งในตอนนี้และในอนาคต

ฉันควรพูดถึงว่าฉันกำลังสร้างเครื่องมือ (ไม่ใช่เว็บไซต์ธรรมดา ๆ ) ที่มีปุ่มมากมายองค์ประกอบ UI การลากวางผู้ฟัง / ตัวจัดการการกระทำและฟังก์ชันในขอบเขตทั่วโลกซึ่งผู้ฟังหลายคนอาจใช้ฟังก์ชันเดียวกัน

ตัวอย่างรหัส

$('#button1').on('click', function(e){
    // Determined action.
    update_html();
});

... // Around 75 more of this

function update_html(){ .... }

...

โค้ดตัวอย่างเพิ่มเติม

สรุป

ฉันจำเป็นต้องจัดระเบียบรหัสนี้เพื่อการใช้งานที่ดีที่สุดและไม่ต้องทำซ้ำตัวเองและสามารถเพิ่มคุณสมบัติใหม่และอัปเดตโค้ดเก่าได้ ฉันจะทำงานนี้ด้วยตัวเอง ตัวเลือกบางตัวสามารถเป็นโค้ดได้ 100 บรรทัดอื่น ๆ คือ 1 ฉันได้ดูเล็กน้อยrequire.jsและพบว่ามันซ้ำซากและเขียนโค้ดมากกว่าที่ต้องการจริงๆ ฉันเปิดรับโซลูชันที่เป็นไปได้ที่ตรงกับเกณฑ์นี้และลิงก์ไปยังแหล่งข้อมูล / ตัวอย่างจะเป็นข้อดีเสมอ

ขอบคุณ.


หากคุณต้องการเพิ่ม backbone.js และ require.js มันจะเป็นงานมาก
jantimon

1
คุณพบว่าตัวเองทำงานอะไรซ้ำแล้วซ้ำเล่าเมื่อเขียนสิ่งนี้
Mike Samuel

4
คุณเคยเยี่ยมชมcodereview.stackexchange.comหรือไม่
Antony

4
เรียนรู้ Angular! มันคืออนาคต
Onur Yıldırım

2
รหัสของคุณไม่ควรอยู่ที่ลิงค์ภายนอกควรอยู่ที่นี่ นอกจากนี้ @codereview ยังเป็นสถานที่ที่ดีกว่าสำหรับคำถามประเภทต่างๆ
George Stocker

คำตอบ:


98

ฉันจะพูดถึงสิ่งง่ายๆที่อาจช่วยคุณหรือไม่ก็ได้ บางคนอาจจะเห็นได้ชัดบางคนอาจมีความลึกลับอย่างมาก

ขั้นตอนที่ 1: แบ่งรหัสของคุณ

การแยกโค้ดของคุณออกเป็นหลาย ๆ หน่วยแบบแยกส่วนเป็นขั้นตอนแรกที่ดีมาก ปัดเศษสิ่งที่ "ทำงานร่วมกัน" และวางไว้ในหน่วยห่อเล็ก ๆ ของพวกเขาเอง ไม่ต้องกังวลเกี่ยวกับรูปแบบในตอนนี้เก็บไว้ในบรรทัด โครงสร้างเป็นจุดต่อมา

สมมติว่าคุณมีหน้าดังนี้:

ป้อนคำอธิบายภาพที่นี่

มันจะสมเหตุสมผลที่จะแบ่งส่วนเพื่อให้ตัวจัดการ / ตัวยึดเหตุการณ์ที่เกี่ยวข้องกับส่วนหัวทั้งหมดอยู่ในนั้นเพื่อความสะดวกในการบำรุงรักษา (และไม่ต้องร่อนถึง 1,000 บรรทัด)

จากนั้นคุณสามารถใช้เครื่องมือเช่น Grunt เพื่อสร้าง JS ของคุณใหม่กลับเป็นหน่วยเดียว

ขั้นตอนที่ 1a: การจัดการการพึ่งพา

ใช้ห้องสมุดเช่น RequireJS หรือ CommonJS ที่จะใช้สิ่งที่เรียกว่าเอเอ็มดี การโหลดโมดูลแบบอะซิงโครนัสช่วยให้คุณระบุได้อย่างชัดเจนว่าโค้ดของคุณขึ้นอยู่กับอะไรซึ่งจะช่วยให้คุณสามารถยกเลิกการเรียกไลบรารีไปยังรหัสได้ คุณสามารถเพียงแค่ตัวอักษรบอกว่า "นี้ต้อง jQuery" และเอเอ็มดีจะโหลดและรันโค้ดของคุณเมื่อ jQuery ใช้ได้

สิ่งนี้ยังมีอัญมณีที่ซ่อนอยู่: การโหลดไลบรารีจะเสร็จสิ้นในวินาทีที่ DOM พร้อมไม่ใช่ก่อนหน้านี้ สิ่งนี้จะไม่หยุดการโหลดหน้าเว็บของคุณอีกต่อไป!

ขั้นตอนที่ 2: Modularize

เห็นโครงร่างไหม ฉันมีหน่วยโฆษณาสองหน่วย พวกเขามักจะแบ่งปันผู้ฟังเหตุการณ์

งานของคุณในขั้นตอนนี้คือการระบุจุดซ้ำในรหัสของคุณและพยายามที่จะสังเคราะห์ทั้งหมดนี้ในโมดูล ตอนนี้โมดูลจะครอบคลุมทุกอย่าง เราจะแยกสิ่งต่างๆออกไป

แนวคิดทั้งหมดของขั้นตอนนี้คือเริ่มต้นจากขั้นตอนที่ 1 และลบสำเนาพาสต้าทั้งหมดเพื่อแทนที่ด้วยหน่วยที่อยู่คู่กันอย่างหลวม ๆ ดังนั้นแทนที่จะมี:

ad_unit1.js

 $("#au1").click(function() { ... });

ad_unit2.js

 $("#au2").click(function() { ... });

ฉันจะมี:

ad_unit.js:

 var AdUnit = function(elem) {
     this.element = elem || new jQuery();
 }
 AdUnit.prototype.bindEvents = function() {
     ... Events go here
 }

page.js:

 var AUs = new AdUnit($("#au1,#au2"));
 AUs.bindEvents();

ซึ่งช่วยให้คุณสามารถแบ่งส่วนระหว่างเหตุการณ์และมาร์กอัปของคุณได้นอกเหนือจากการกำจัดความซ้ำซากจำเจ นี่เป็นขั้นตอนที่ดีทีเดียวและเราจะขยายไปในภายหลัง

ขั้นตอนที่ 3: เลือกกรอบงาน!

หากคุณต้องการโมดูลาร์และลดการทำซ้ำให้ดียิ่งขึ้นมีกรอบงานที่ยอดเยี่ยมมากมายที่ใช้แนวทาง MVC (Model - View - Controller) สิ่งที่ฉันชอบคือกระดูกสันหลัง / กระดูกสันหลังอย่างไรก็ตามยังมี Angular, Yii, ...

รุ่นหมายถึงข้อมูลของคุณ

ดูหมายถึงเครื่องหมายขึ้นของคุณและเหตุการณ์ทั้งหมดที่เกี่ยวข้องกับมัน

ควบคุมหมายถึงตรรกะทางธุรกิจของคุณ - ในคำอื่น ๆ ควบคุมบอกหน้าสิ่งที่มองเห็นวิวโหลดและสิ่งที่รูปแบบการใช้งาน

นี่จะเป็นขั้นตอนการเรียนรู้ที่สำคัญ แต่รางวัลที่ได้รับก็คุ้มค่า: มันช่วยให้โค้ดแบบโมดูลาร์สะอาดตามากกว่าสปาเก็ตตี้

ยังมีสิ่งอื่น ๆ อีกมากมายที่คุณสามารถทำได้ซึ่งเป็นเพียงแนวทางและแนวคิดเท่านั้น

การเปลี่ยนแปลงเฉพาะรหัส

การปรับปรุงโค้ดของคุณมีดังนี้:

 $('.new_layer').click(function(){

    dialog("Create new layer","Enter your layer name","_input", {

            'OK' : function(){

                    var reply = $('.dialog_input').val();

                    if( reply != null && reply != "" ){

                            var name = "ln_"+reply.split(' ').join('_');
                            var parent = "";

                            if(selected_folder != "" ){
                            parent = selected_folder+" .content";
                            }

                            $R.find(".layer").clone()
                            .addClass(name).html(reply)
                            .appendTo("#layer_groups "+parent);

                            $R.find(".layers_group").clone()
                            .addClass(name).appendTo('#canvas '+selected_folder);

            }

        }

    });
 });

ดีกว่าเขียนเป็น:

$("body").on("click",".new_layer", function() {
    dialog("Create new layer", "Enter your layer name", "_input", {
         OK: function() {
             // There must be a way to get the input from here using this, if it is a standard library. If you wrote your own, make the value retrievable using something other than a class selector (horrible performance + scoping +multiple instance issues)

             // This is where the view comes into play. Instead of cloning, bind the rendering into a JS prototype, and instantiate it. It means that you only have to modify stuff in one place, you don't risk cloning events with it, and you can test your Layer stand-alone
             var newLayer = new Layer();
             newLayer
               .setName(name)
               .bindToGroup(parent);
          }
     });
});

ก่อนหน้านี้ในรหัสของคุณ:

window.Layer = function() {
    this.instance = $("<div>");
    // Markup generated here
};
window.Layer.prototype = {
   setName: function(newName) {
   },
   bindToGroup: function(parentNode) {
   }
}

ทันใดนั้นคุณมีวิธีสร้างเลเยอร์มาตรฐานจากที่ใดก็ได้ในโค้ดของคุณโดยไม่ต้องคัดลอกวาง คุณกำลังทำสิ่งนี้ในสถานที่ต่างๆห้าแห่ง ฉันเพิ่งบันทึกคุณได้ห้าสำเนา

อีกหนึ่ง:

// เสื้อคลุมกฎสำหรับการดำเนินการ

var PageElements = function(ruleSet) {
ruleSet = ruleSet || [];
this.rules = [];
for (var i = 0; i < ruleSet.length; i++) {
    if (ruleSet[i].target && ruleSet[i].action) {
        this.rules.push(ruleSet[i]);
    }
}
}
PageElements.prototype.run = function(elem) {
for (var i = 0; i < this.rules.length; i++) {
    this.rules[i].action.apply(elem.find(this.rules.target));
}
}

var GlobalRules = new PageElements([
{
    "target": ".draggable",
    "action": function() { this.draggable({
        cancel: "div#scrolling, .content",
        containment: "document"
        });
    }
},
{
    "target" :".resizable",
    "action": function() {
        this.resizable({
            handles: "all",
            zIndex: 0,
            containment: "document"
        });
    }
}

]);

GlobalRules.run($("body"));

// If you need to add elements later on, you can just call GlobalRules.run(yourNewElement);

นี่เป็นวิธีที่มีประสิทธิภาพมากในการลงทะเบียนกฎหากคุณมีเหตุการณ์ที่ไม่ได้มาตรฐานหรือเหตุการณ์ที่สร้างขึ้น นอกจากนี้ยังเป็นการเตะตูดอย่างจริงจังเมื่อรวมกับระบบการแจ้งเตือนผับ / ย่อยและเมื่อเชื่อมโยงกับเหตุการณ์ที่คุณเริ่มทำงานเมื่อใดก็ตามที่คุณสร้างองค์ประกอบ การผูกเหตุการณ์แบบโมดูลาร์ Fire'n'forgettable!


2
@ เจสสิก้า: ทำไมเครื่องมือออนไลน์ถึงแตกต่างกัน? วิธีการนี้ยังคงเหมือนเดิม: แยกส่วน / โมดูลาร์, ส่งเสริมการมีเพศสัมพันธ์แบบหลวม ๆ ระหว่างส่วนประกอบโดยใช้เฟรมเวิร์ก (ทั้งหมดนี้มาพร้อมกับการมอบหมายเหตุการณ์ในปัจจุบัน) แยกรหัสของคุณออกจากกัน มีอะไรที่ใช้ไม่ได้กับเครื่องมือของคุณที่นั่น? ความจริงที่ว่าคุณมีปุ่มมากมาย?
Sébastien Renauld

2
@ เจสสิก้า: อัพเดท ฉันได้ทำให้การสร้างเลเยอร์ง่ายขึ้นและคล่องตัวขึ้นโดยใช้แนวคิดที่คล้ายกับไฟล์View. ดังนั้น. วิธีนี้ใช้ไม่ได้กับรหัสของคุณ?
Sébastien Renauld

10
@ เจสสิก้า: การแยกไฟล์โดยไม่ปรับให้เหมาะสมก็เหมือนกับการซื้อลิ้นชักเพิ่มเพื่อเก็บขยะ วันหนึ่งคุณต้องเคลียร์และมันง่ายกว่าที่จะเคลียร์ก่อนที่ลิ้นชักจะเต็ม ทำไมไม่ทำทั้งสองอย่าง? ตอนนี้ดูเหมือนว่าคุณจะต้องการlayers.js, sidebar.js, global_events.js, resources.js, files.js, dialog.jsถ้าคุณกำลังจะแยกรหัสของคุณขึ้นมา ใช้gruntเพื่อสร้างใหม่ให้เป็นหนึ่งเดียวและGoogle Closure Compilerรวบรวมและย่อเล็กสุด
Sébastien Renauld

3
เมื่อใช้ require.js คุณต้องดูเครื่องมือเพิ่มประสิทธิภาพ r.js ด้วยเช่นกันนี่คือสิ่งที่ทำให้ต้องใช้ js คุ้มค่า มันจะรวมและเพิ่มประสิทธิภาพไฟล์ทั้งหมดของคุณ: requirejs.org/docs/optimization.html
Willem D'Haeseleer

2
@ SébastienRenauldคำตอบและความคิดเห็นของคุณยังคงได้รับการชื่นชมจากผู้ใช้รายอื่น ถ้านั่นทำให้คุณรู้สึกดีขึ้นได้;)
Adrien Be

13

นี่คือวิธีง่ายๆในการแบ่ง codebase ปัจจุบันของคุณออกเป็นหลายไฟล์โดยใช้ require.js ฉันจะแสดงวิธีแยกรหัสของคุณออกเป็นสองไฟล์ การเพิ่มไฟล์เพิ่มเติมจะตรงไปตรงมาหลังจากนั้น

ขั้นตอนที่ 1)ที่ด้านบนสุดของรหัสของคุณให้สร้างวัตถุแอป (หรือชื่ออะไรก็ได้ที่คุณต้องการเช่น MyGame):

var App = {}

ขั้นตอนที่ 2)แปลงตัวแปรและฟังก์ชันระดับบนสุดทั้งหมดของคุณให้เป็นของวัตถุ App

แทน:

var selected_layer = "";

คุณต้องการ:

App.selected_layer = "";

แทน:

function getModified(){
...
}

คุณต้องการ:

App.getModified = function() {

}

โปรดทราบว่า ณ จุดนี้รหัสของคุณจะใช้ไม่ได้จนกว่าคุณจะเสร็จสิ้นขั้นตอนถัดไป

ขั้นตอนที่ 3)แปลงการอ้างอิงตัวแปรและฟังก์ชันทั่วโลกทั้งหมดเพื่อผ่านแอพ

เปลี่ยนสิ่งต่างๆเช่น:

selected_layer = "."+classes[1];

ถึง:

App.selected_layer = "."+classes[1];

และ:

getModified()

ถึง:

App.GetModified()

ขั้นตอนที่ 4)ทดสอบรหัสของคุณในขั้นตอนนี้ - ทุกอย่างควรใช้งานได้ คุณอาจจะได้รับข้อผิดพลาดเล็กน้อยในตอนแรกเนื่องจากคุณพลาดบางสิ่งไปดังนั้นให้แก้ไขข้อผิดพลาดนั้นก่อนที่จะดำเนินการต่อ

ขั้นตอนที่ 5)ตั้งค่าข้อกำหนด ฉันถือว่าคุณมีหน้าเว็บที่ให้บริการจากเว็บเซิร์ฟเวอร์ซึ่งมีรหัสอยู่ใน:

www/page.html

และ jquery ใน

www/js/jquery.js

หากเส้นทางเหล่านี้ไม่ตรงตามนี้ทุกประการด้านล่างจะใช้ไม่ได้และคุณจะต้องแก้ไขเส้นทาง

ดาวน์โหลดrequirejsและใส่ require.js ในwww/jsไดเร็กทอรีของคุณ

ในของคุณpage.htmlลบแท็กสคริปต์ทั้งหมดและแทรกแท็กสคริปต์เช่น:

<script data-main="js/main" src="js/require.js"></script>

สร้างwww/js/main.jsด้วยเนื้อหา:

require.config({
 "shim": {
   'jquery': { exports: '$' }
 }
})

require(['jquery', 'app']);

จากนั้นใส่รหัสทั้งหมดที่คุณเพิ่งแก้ไขในขั้นตอนที่ 1-3 (ซึ่งตัวแปรส่วนกลางเท่านั้นที่ควรเป็น App) ใน:

www/js/app.js

ที่ด้านบนสุดของไฟล์นั้นให้ใส่:

require(['jquery'], function($) {

ที่ด้านล่างใส่:

})

จากนั้นโหลด page.html ในเบราว์เซอร์ของคุณ แอปของคุณควรใช้งานได้!

ขั้นตอนที่ 6)สร้างไฟล์อื่น

ที่นี่คือที่ที่งานของคุณให้ผลตอบแทนคุณสามารถทำสิ่งนี้ซ้ำแล้วซ้ำอีก

ดึงรหัสบางส่วนจากwww/js/app.jsการอ้างอิง $ และ App

เช่น

$('a').click(function() { App.foo() }

ใส่เข้าไป www/js/foo.js

ที่ด้านบนสุดของไฟล์นั้นให้ใส่:

require(['jquery', 'app'], function($, App) {

ที่ด้านล่างใส่:

})

จากนั้นเปลี่ยนบรรทัดสุดท้ายของ www / js / main.js เป็น:

require(['jquery', 'app', 'foo']);

แค่นั้นแหละ! ทำทุกครั้งที่ต้องการใส่โค้ดในไฟล์ของมันเอง!


ปัญหานี้มีหลายปัญหา - ปัญหาที่ชัดเจนคือคุณกำลังแยกส่วนไฟล์ทั้งหมดของคุณในตอนท้ายและบังคับให้ข้อมูลที่สูญเปล่า 400 ไบต์ไปยังผู้ใช้ทุกคนต่อสคริปต์ต่อการโหลดหน้าโดยไม่ใช้ตัวr.jsประมวลผลล่วงหน้า นอกจากนี้คุณยังไม่ได้แก้ไขปัญหาของ OP - เป็นเพียงวิธีการทั่วไปrequire.jsเท่านั้น
Sébastien Renauld

7
ฮะ? คำตอบของฉันเฉพาะสำหรับคำถามนี้ เห็นได้ชัดว่า r.js เป็นขั้นตอนต่อไป แต่ปัญหาที่นี่คือการจัดระเบียบไม่ใช่การเพิ่มประสิทธิภาพ
Lyn Headley

ฉันชอบคำตอบนี้ฉันไม่เคยใช้ require.js ดังนั้นฉันจะต้องดูว่าฉันสามารถใช้มันและได้รับประโยชน์จากมันหรือไม่ ฉันใช้รูปแบบโมดูลอย่างหนัก แต่บางทีนี่อาจจะทำให้ฉันสามารถสรุปบางสิ่งออกไปแล้วต้องการมันเข้ามา
Tony

1
@ SébastienRenauld: คำตอบนี้ไม่ได้เกี่ยวกับ require.js เท่านั้น ส่วนใหญ่พูดถึงการมีเนมสเปซสำหรับโค้ดที่คุณกำลังสร้าง ฉันคิดว่าคุณควรจะขอบคุณในส่วนที่ดีและทำการแก้ไขหากคุณพบปัญหาใด ๆ :)
mithunsatheesh

10

สำหรับคำถามและความคิดเห็นของคุณฉันจะถือว่าคุณไม่เต็มใจที่จะพอร์ตโค้ดของคุณไปยังเฟรมเวิร์กเช่น Backbone หรือใช้ไลบรารีตัวโหลดเช่น Require คุณแค่ต้องการวิธีที่ดีกว่าในการสร้างรหัสที่คุณมีอยู่แล้วให้ดีขึ้นด้วยวิธีที่ง่ายที่สุดเท่าที่จะทำได้

ฉันเข้าใจว่ามันน่ารำคาญที่ต้องเลื่อนดูโค้ดมากกว่า 2,000 บรรทัดเพื่อค้นหาส่วนที่คุณต้องการใช้งาน วิธีแก้ปัญหาคือการแยกรหัสของคุณในไฟล์ต่างๆหนึ่งไฟล์สำหรับแต่ละฟังก์ชัน ตัวอย่างเช่นsidebar.js, canvas.jsเป็นต้นจากนั้นคุณสามารถเข้าร่วมพวกเขาร่วมกันสำหรับการผลิตโดยใช้ฮึดฮัดร่วมกับ Usemin คุณสามารถมีบางอย่างเช่นนี้

ใน html ของคุณ:

<!-- build:js scripts/app.js -->
<script src="scripts/sidebar.js"></script>
<script src="scripts/canvas.js"></script>
<!-- endbuild -->

ใน Gruntfile ของคุณ:

useminPrepare: {
  html: 'app/index.html',
  options: {
    dest: 'dist'
  }
},
usemin: {
  html: ['dist/{,*/}*.html'],
  css: ['dist/styles/{,*/}*.css'],
  options: {
    dirs: ['dist']
  }
}

หากคุณต้องการใช้ Yeoman มันจะให้รหัสสำเร็จรูปสำหรับทั้งหมดนี้

จากนั้นสำหรับแต่ละไฟล์คุณต้องแน่ใจว่าคุณปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดและโค้ดและตัวแปรทั้งหมดอยู่ในไฟล์นั้นและไม่ขึ้นอยู่กับไฟล์อื่น ๆ นี่ไม่ได้หมายความว่าคุณไม่สามารถเรียกฟังก์ชันของไฟล์หนึ่งจากไฟล์อื่นได้ประเด็นคือต้องมีตัวแปรและฟังก์ชันที่ห่อหุ้มไว้ สิ่งที่คล้ายกับการกำหนดเนมสเปซ ฉันจะถือว่าคุณไม่ต้องการพอร์ตโค้ดทั้งหมดของคุณเป็น Object Oriented แต่ถ้าคุณไม่สนใจที่จะปรับโครงสร้างใหม่สักหน่อยฉันขอแนะนำให้เพิ่มสิ่งที่เทียบเท่ากับสิ่งที่เรียกว่ารูปแบบโมดูล มีลักษณะดังนี้:

sidebar.js

var Sidebar = (function(){
// functions and vars here are private
var init = function(){
  $("#sidebar #sortable").sortable({
            forceHelperSize: true,
            forcePlaceholderSize: true,
            revert: true,
            revert: 150,
            placeholder: "highlight panel",
            axis: "y",
            tolerance: "pointer",
            cancel: ".content"
       }).disableSelection();
  } 
  return {
   // here your can put your "public" functions
   init : init
  }
})();

จากนั้นคุณสามารถโหลดบิตของโค้ดนี้ได้ดังนี้:

$(document).ready(function(){
   Sidebar.init();
   ...

วิธีนี้จะช่วยให้คุณมีโค้ดที่ดูแลรักษาได้มากขึ้นโดยไม่ต้องเขียนโค้ดซ้ำมากเกินไป


1
คุณอาจต้องการที่จะพิจารณาอย่างจริงจังที่สองที่ผ่านมาข้อมูลโค้ดซึ่งไม่ดีกว่ารหัสการเขียนแบบอินไลน์: #sidebar #sortableโมดูลของคุณต้องการ คุณสามารถบันทึกหน่วยความจำของตัวเองได้เช่นกันโดยเพียงแค่ใส่โค้ดเข้าไปและบันทึก IETF สองตัว
Sébastien Renauld

ประเด็นก็คือคุณสามารถใช้รหัสอะไรก็ได้ที่คุณต้องการ ฉันแค่ใช้ตัวอย่างจากรหัสเดิม
Jesús Carrera

ฉันเห็นด้วยกับพระเยซูนี่เป็นเพียงตัวอย่าง OP สามารถเพิ่มตัวเลือก "วัตถุ" ได้อย่างง่ายดายซึ่งจะช่วยให้พวกเขาระบุตัวเลือกขององค์ประกอบแทนที่จะเข้ารหัสยาก แต่นี่เป็นเพียงตัวอย่างสั้น ๆ ฉันอยากจะบอกว่าฉันชอบรูปแบบโมดูลซึ่งเป็นรูปแบบหลักที่ฉันใช้ แต่ถึงอย่างนั้นฉันก็ยังพยายามจัดระเบียบโค้ดให้ดีขึ้น ฉันใช้ C # ตามปกติดังนั้นการตั้งชื่อและการสร้างฟังก์ชันจึงเป็นเรื่องธรรมดา ฉันพยายามรักษา "รูปแบบ" ไว้เช่นขีดล่างเป็นแบบโลคัลและแบบส่วนตัวตัวแปรเป็นเพียง "อ็อบเจกต์" จากนั้นฉันก็อ้างอิงฟังก์ชันในการส่งคืนซึ่งเป็นแบบสาธารณะ
Tony

อย่างไรก็ตามฉันยังคงพบความท้าทายกับแนวทางนี้และปรารถนาที่จะมีวิธีที่ดีกว่าในการทำเช่นนี้ แต่มันใช้งานได้ดีกว่าการประกาศตัวแปรและฟังก์ชั่นของฉันในพื้นที่ทั่วโลกเพื่อทำให้เกิดความขัดแย้งกับ js อื่น ๆ .... lol
Tony

6

ใช้ javascript MVC Framework เพื่อจัดระเบียบโค้ดจาวาสคริปต์ด้วยวิธีมาตรฐาน

เฟรมเวิร์ก JavaScript MVC ที่ดีที่สุดมีดังนี้:

การเลือกเฟรมเวิร์ก JavaScript MVC จำเป็นต้องมีปัจจัยมากมายที่ต้องพิจารณา อ่านบทความเปรียบเทียบต่อไปนี้ซึ่งจะช่วยให้คุณเลือกเฟรมเวิร์กที่ดีที่สุดตามปัจจัยที่สำคัญสำหรับโครงการของคุณ: http://sporto.github.io/blog/2013/04/12/comparison-angular-backbone-can-ember/

คุณยังสามารถใช้RequireJSกับเฟรมเวิร์กเพื่อรองรับไฟล์ Asynchrounous js และการโหลดโมดูล
ดูด้านล่างเพื่อเริ่มการโหลดโมดูล JS:
http://www.sitepoint.com/understand-requirejs-for-effective-javascript-module-loading/


4

จัดหมวดหมู่รหัสของคุณ วิธีนี้ช่วยฉันได้มากและใช้ได้กับ js framework ใด ๆ :

(function(){//HEADER: menu
    //your code for your header
})();
(function(){//HEADER: location bar
    //your code for your location
})();
(function(){//FOOTER
    //your code for your footer
})();
(function(){//PANEL: interactive links. e.g:
    var crr = null;
    $('::section.panel a').addEvent('click', function(E){
        if ( crr) {
            crr.hide();
        }
        crr = this.show();
    });
})();

ในโปรแกรมแก้ไขที่คุณต้องการ (ที่ดีที่สุดคือ Komodo Edit) คุณสามารถพับได้โดยการยุบรายการทั้งหมดและคุณจะเห็นเฉพาะชื่อเรื่อง:

(function(){//HEADER: menu_____________________________________
(function(){//HEADER: location bar_____________________________
(function(){//FOOTER___________________________________________
(function(){//PANEL: interactive links. e.g:___________________

2
+1 สำหรับโซลูชัน JS มาตรฐานที่ไม่ต้องพึ่งพาไลบรารี
hobberwickey

-1 ด้วยเหตุผลหลายประการ รหัสเทียบเท่าของคุณเหมือนกับ OP ของ ... + หนึ่ง IETF ต่อ "ส่วน" นอกจากนี้คุณกำลังใช้ตัวเลือกที่กว้างเกินไปโดยไม่อนุญาตให้นักพัฒนาโมดูลแทนที่การสร้าง / ลบสิ่งเหล่านั้นหรือเพื่อขยายพฤติกรรม สุดท้าย IETF ไม่ฟรี
Sébastien Renauld

@hobberwickey: ไม่รู้เกี่ยวกับคุณ แต่ฉันอยากจะพึ่งพาสิ่งที่ขับเคลื่อนโดยชุมชนและจุดบกพร่องจะพบได้อย่างรวดเร็วถ้าฉันทำได้ โดยเฉพาะอย่างยิ่งถ้าทำอย่างอื่นจะประณามฉันในการประดิษฐ์ล้อใหม่
Sébastien Renauld

2
ทั้งหมดนี้คือการจัดระเบียบรหัสเป็นส่วนที่ไม่ต่อเนื่อง ครั้งล่าสุดที่ฉันตรวจสอบนั่นคือ A: แนวทางปฏิบัติที่ดีและ B: ไม่ใช่สิ่งที่คุณต้องการจริงๆสำหรับห้องสมุดที่ชุมชนรองรับ ไม่ใช่ทุกโปรเจ็กต์ที่พอดีกับ Backbone, Angular และอื่น ๆ และการสร้างโค้ดแบบแยกส่วนโดยการรวมไว้ในฟังก์ชันเป็นวิธีแก้ปัญหาทั่วไปที่ดี
hobberwickey

เป็นไปได้ทุกเวลาที่คุณต้องการพึ่งพาห้องสมุดที่ชื่นชอบเพื่อใช้แนวทางนี้ แต่โซลูชันข้างต้นใช้งานได้กับ javascript, ไลบรารีที่กำหนดเองหรือเฟรมเวิร์ก js ที่มีชื่อเสียง

3

ฉันจะแนะนำ:

  1. รูปแบบผู้เผยแพร่ / สมาชิกสำหรับการจัดการเหตุการณ์
  2. การวางแนววัตถุ
  3. namespacing

ในกรณีของคุณเจสสิก้าแบ่งอินเทอร์เฟซออกเป็นหน้าหรือหน้าจอ เพจหรือหน้าจอสามารถเป็นอ็อบเจ็กต์และขยายจากคลาสพาเรนต์บางคลาส จัดการการโต้ตอบระหว่างเพจด้วยคลาส PageManager


คุณสามารถขยายสิ่งนี้ด้วยตัวอย่าง / แหล่งข้อมูลได้หรือไม่?
Kivylius

1
"การวางแนววัตถุ" หมายความว่าอย่างไร เกือบทุกอย่างใน JS เป็นวัตถุ และไม่มีคลาสใน JS
Bergi

2

ฉันขอแนะนำให้คุณใช้บางอย่างเช่น Backbone Backbone คือไลบรารีจาวาสคริปต์ที่สนับสนุน RESTFUL Ik ทำให้โค้ดของคุณสะอาดขึ้นและอ่านง่ายขึ้นและมีประสิทธิภาพเมื่อใช้ร่วมกับ requirejs

http://backbonejs.org/

http://requirejs.org/

กระดูกสันหลังไม่ใช่ห้องสมุดจริง หมายถึงการให้โครงสร้างกับโค้ดจาวาสคริปต์ของคุณ มันสามารถรวมไลบรารีอื่น ๆ เช่น jquery, jquery-ui, google-maps เป็นต้นในความคิดของฉัน Backbone เป็นวิธีการที่ใกล้เคียงที่สุดกับจาวาสคริปต์สำหรับโครงสร้าง Object Oriented และ Model View Controller

เกี่ยวกับเวิร์กโฟลว์ของคุณด้วย .. หากคุณสร้างแอปพลิเคชันของคุณใน PHP ให้ใช้ไลบรารี Laravel มันจะทำงานร่วมกับ Backbone ได้อย่างไม่มีที่ติเมื่อใช้กับหลักการ RESTfull ด้านล่างลิงก์ไปยัง Laravel Framework และบทช่วยสอนเกี่ยวกับการสร้าง RESTfull APIs:

http://maxoffsky.com/code-blog/building-restful-api-in-laravel-start-here/

http://laravel.com/

ด้านล่างนี้เป็นบทช่วยสอนจาก nettuts Nettuts มีบทเรียนคุณภาพสูงมากมาย:

http://net.tutsplus.com/tutorials/javascript-ajax/understand-backbone-js-and-the-server/


0

บางทีเวลาสำหรับคุณเริ่มต้นการดำเนินการพัฒนาทั้งขั้นตอนการทำงานโดยใช้เครื่องมือเช่นเสรีชนhttp://yeoman.io/ สิ่งนี้จะช่วยควบคุมการอ้างอิงทั้งหมดของคุณกระบวนการสร้างและการทดสอบอัตโนมัติหากคุณต้องการ มีงานมากมายที่ต้องเริ่มต้น แต่เมื่อนำไปใช้แล้วจะทำให้การเปลี่ยนแปลงในอนาคตง่ายขึ้นมาก

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.