


Detaillierte Erläuterung des Loader-Prinzips der modularen JavaScript-Programmierung
Es gibt viele JavaScript-Loader auf der Welt, wie z. B. sea.js, require.js, yui Loader, labJs…. Der Einsatzbereich von Loadern ist für einige relativ große Projekte Für kleine Projekte ist dies nicht erforderlich. RequireJS ist mit AMD kompatibel und der vollständige Name lautet (Asynchronous Module Definition). ist ein Loader, der der CMD-Spezifikation entspricht.
AMD__ und __CMD
Die AMD-Spezifikation ist die Weiterleitung von Abhängigkeiten, die CMD-Spezifikation ist die Nachpositionierung von Abhängigkeiten und der Loader der AMD-Spezifikation führt alle Abhängigkeiten im Voraus in JS aus. Wenn JS dieses Modul benötigt, wird es nicht geladen. Das durch den Loader (requireJS) verursachte Problem kann zum ersten Mal lange dauern weil es alle abhängigen JS lädt. Laden Sie sie alle auf einmal herunter.
Der gesunde Menschenverstand unterstützt die AMD-Spezifikation und nicht die CMD-Spezifikation. Mit anderen Worten: Wenn Sie seaJS einführen und jQuery verwenden möchten, müssen Sie dies tun Verwenden Sie die Alias-Konfiguration oder konfigurieren Sie http://www.php.cn/ direkt in die Seite
//这是jQuery源码的最后几行, jQuery到了1.7才支持模块化; // Register as a named AMD module, since jQuery can be concatenated with other // files that may use define, but not via a proper concatenation script that // understands anonymous AMD modules. A named AMD is safest and most robust // way to register. Lowercase jquery is used because AMD module names are // derived from file names, and jQuery is normally delivered in a lowercase // file name. Do this after creating the global so that if an AMD module wants // to call noConflict to hide this version of jQuery, it will work. // Note that for maximum portability, libraries that are not jQuery should // declare themselves as anonymous modules, and avoid setting a global if an // AMD loader is present. jQuery is a special case. For more information, see // http://www.php.cn/ if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; }); };
Verwendung
Zum Beispiel können wir ein Modul wie folgt definieren:
//文件所在的路径地址为:http://www.php.cn/:63342/module/script/dir2/1.js define(function() { return "!!!!"; });
Definieren Sie auch ein Modul wie folgt:
//这个文件的路径为http://www.php.cn/:63342/module/main.js , 而且有一个依赖, 加载器会自动去加载这个依赖, 当依赖加载完毕以后, 会把这个依赖(就是script/dir2/1.js)执行的返回值作为这个函数的参数传进去; require(["script/dir2/1.js"], function(module1) { console.log(module1); }); //实际上会打印出 "!!!!"
Im Allgemeinen kann ein Modul nur eine Definitionsfunktion schreiben. Es gibt zwei Hauptmethoden, um Parameter an die Definitionsfunktion zu übergeben:
1: Normalerweise kann es eine Funktion sein;
2: Es kann eine Liste von Array-Typabhängigkeiten sein und eine Funktion
Wenn ein Modul mehrere Definitionen schreibt, Dies führt zu einer Fehlfunktion des Moduls und das zuerst definierte Modul wird später abgedeckt (natürlich spielen wir nicht so).
Es können mehrere Anforderungen in ein Modul geschrieben werden. Wir können „require“ direkt als anonymes Definitionsmodul verstehen. In einem „require“-Modul können mehrere Anforderungen vorliegen, und die erforderlichen Module werden normalerweise innerhalb des -Abschlusses zwischengespeichert Namen sind Module oder so...;
Wir verwenden den Loader. Die modulare Entwicklung muss sich an einen Standard halten. Wenn ein Modul als JS standardisiert ist, können wir mehrere neue Verzeichnisse für Controller, Ansicht und Modell erstellen . Dies dient auch der besseren Wartung und Entkopplung in der Zukunft:
Implementieren Sie einen eigenen Lader
Die verwendete Methode:
//这个模块依赖的四个模块,加载器会分别去加载这四个模块; define(["依赖0","依赖1","依赖2","依赖3"], function(依赖0,依赖1,依赖2,依赖3){ }); //返回一个空对象 define(function(){ return {}; }); //直接把require当作是define来用就好了; require(["依赖0","依赖1","依赖2","依赖3"], function(依赖0,依赖1,依赖2,依赖3) { //执行依赖0; 依赖0(依赖1,依赖2,依赖3); }); //这个加载器define函数和require函数的区别是,define我们可以传个name作为第一参数, 这个参数就是模块的名字, 好吧, 不管这些了.....;
Das Folgende ist die Struktur des Loaders, da die Codemenge bereits sehr gering ist. Daher ist jede Funktion erforderlich. Um die globale Situation nicht zu beeinträchtigen, fügen Sie den Code in die anonyme selbstausführende Funktion ein:
(function() { 定义一个局部的difine; var define; //我偷偷加了个全局变量,好调试啊; window.modules = { }; //通过一个名字获取绝对路径比如传"xx.js"会变成"http://www.mm.com/"+ baseUrl + "xx.html"; var getUrl = function(src) {}; //动态加载js的模块; var loadScript = function(src) {}; //获取根路径的方法, 一般来说我们可以通过config.baseUrl配置这个路径; var getBasePath = function() {}; //获取当前正在加载的script标签DOM节点; var getCurrentNode = function() {}; //获取当前script标签的绝对src地址; var getCurrentPath = function() {}; //加载define或者require中的依赖, 封装了loadScript方法; var loadDpt = function(module) {}; //这个是主要模块, 完成了加载依赖, 检测依赖等比较重要的逻辑 var checkDps = function() {}; 定义了define这个方法 define = function(deps, fn, name) {}; window.define = define; //require是封装了define的方法, 就是多传了一个参数而已; window.require = function() { //如果是require的话那么模块的名字就是一个不重复的名字,避免和define重名; window.define.apply([], Array.prototype.slice.call(arguments).concat( "module|"+setTimeout(function() {},0) )); }; });
Loader-Quellcode-Implementierung (kompatibel mit Chrome, FF, IE6 ==> > IE11), IE11 verfügt weder über das Attribut „readyState“ noch über das Attribut „currentScript“. Sie können den JS-Pfad derzeit nicht abrufen ausgeführt wird, müssen Sie also einen Hack verwenden.
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script> (function() { var define; window.modules = { }; var getUrl = function(src) { var scriptSrc = ""; //判断URL是否是 // ./或者 // /或者 // 直接是以字符串开头 // 或者是以http://开头; if( src.indexOf("/") === 0 || src.indexOf("./") === 0 ) { scriptSrc = require.config.base + src.replace(/^\//,"").replace(/^\.\//,""); }else if( src.indexOf("http:") === 0 ) { scriptSrc = src; }else if( src.match(/^[a-zA-Z1-9]/) ){ scriptSrc = require.config.base + src; }else if(true) { alert("src错误!"); }; if (scriptSrc.lastIndexOf(".js") === -1) { scriptSrc += ".js"; }; return scriptSrc; }; var loadScript = function(src) { var scriptSrc = getUrl(src); var sc = document.createElement("script"); var head = document.getElementsByTagName("head")[0]; sc.src = scriptSrc; sc.onload = function() { console.log("script tag is load, the url is : " + src); }; head.appendChild( sc ); }; var getBasePath = function() { var src = getCurrentPath(); var index = src.lastIndexOf("/"); return src.substring(0,index+1); }; var getCurrentNode = function() { if(document.currentScript) return document.currentScript; var arrScript = document.getElementsByTagName("script"); var len = arrScript.length; for(var i= 0; i<len; i++) { if(arrScript[i].readyState === "interactive") { return arrScript[i]; }; }; //IE11的特殊处理; var path = getCurrentPath(); for(var i= 0; i<len; i++) { if(path.indexOf(arrScript[i].src)!==-1) { return arrScript[i]; }; }; throw new Error("getCurrentNode error"); }; var getCurrentPath = function() { var repStr = function(str) { return (str || "").replace(/[\&\?]{1}[\w\W]+/g,"") || ""; }; if(document.currentScript) return repStr(document.currentScript.src); //IE11没有了readyState属性, 也没有currentScript属性; // 参考 http://www.php.cn/ var stack try { a.b.c() //强制报错,以便捕获e.stack } catch (e) { //safari的错误对象只有line,sourceId,sourceURL stack = e.stack if (!stack && window.opera) { //opera 9没有e.stack,但有e.Backtrace,但不能直接取得,需要对e对象转字符串进行抽取 stack = (String(e).match(/of linked script \S+/g) || []).join(" ") } } if (stack) { /**e.stack最后一行在所有支持的浏览器大致如下: *chrome23: * at http://www.php.cn/:4:1 *firefox17: *@http://www.php.cn/:4 *opera12:http://www.php.cn/ *@http://www.php.cn/:4 *IE10: * at Global code (http://www.php.cn/:4:1) * //firefox4+ 可以用document.currentScript */ stack = stack.split(/[@ ]/g).pop() //取得最后一行,最后一个空格或@之后的部分 stack = stack[0] === "(" ? stack.slice(1, -1) : stack.replace(/\s/, "") //去掉换行符 return stack.replace(/(:\d+)?:\d+$/i, "") //去掉行号与或许存在的出错字符起始位置 }; //实在不行了就走这里; var node = getCurrentNode(); //IE>=8的直接通过src可以获取,IE67要通过getAttriubte获取src; return repStr(document.querySelector ? node.src : node.getAttribute("src", 4)) || ""; throw new Error("getCurrentPath error!"); }; var loadDpt = function(module) { var dp = ""; for(var p =0; p<module.dps.length; p++) { //获取绝对的地址; var dp = getUrl(module.dps[p]); //如果依赖没有加载就直接加载; if( !modules[dp] ) { loadScript(dp); }; }; }; //主要的模块, 检测所有未加载的模块中未完成了的依赖是否加载完毕,如果加载完毕就加载模块, 如果加载过的话,而且所有依赖的模块加载完毕就执行该模块 //而且此模块的exports为该模块的执行结果; var checkDps = function() { for(var key in modules ) { //初始化该模块需要的参数; var params = []; var module = modules[key]; //加载完毕就什么都不做; if( module.state === "complete" ) { continue; }; if( module.state === "initial" ) { //如果依赖没有加载就加载依赖并且modules没有该module就加载这个模块; loadDpt(module); module.state = "loading"; }; if( module.state === "loading") { //如果这个依赖加载完毕 for(var p =0; p<module.dps.length; p++) { //获取绝对的地址; var dp = getUrl(module.dps[p]); //如果依赖加载完成了, 而且状态为complete;; if( modules[dp] && modules[dp].state === "complete") { params.push( modules[dp].exports ); }; }; //如果依赖全部加载完毕,就执行; if( module.dps.length === params.length ) { if(typeof module.exports === "function"){ module.exports = module.exports.apply(modules,params); module.state = "complete"; //每一次有一个模块加载完毕就重新检测modules,看看是否有未加载完毕的模块需要加载; checkDps(); }; }; }; }; }; //[],fn; fn define = function(deps, fn, name) { if(typeof deps === "function") { fn = deps; deps = [];//我们要把数组清空; }; if( typeof deps !== "object" && typeof fn !== "function") { alert("参数错误") }; var src = getCurrentPath(); //没有依赖, 没有加载该模块就新建一个该模块; if( deps.length===0 ) { modules[ src ] = { name : name || src, src : src, dps : [], exports : (typeof fn === "function")&&fn(), state : "complete" }; return checkDps(); }else{ modules[ src ] = { name : name || src, src : src, dps : deps, exports : fn, state : "initial" }; return checkDps(); } }; window.define = define; window.require = function() { //如果是require的话那么模块的名字就是一个不重复的名字,避免和define重名; window.define.apply([], Array.prototype.slice.call(arguments).concat( "module|"+setTimeout(function() {},0) )); }; require.config = { base : getBasePath() }; require.loadScript = loadScript; var loadDefaultJS = getCurrentNode().getAttribute("data-main"); loadDefaultJS && loadScript(loadDefaultJS); })(); </script> </head> <body> </body> </html>
Einer, der von Ye Dada Loader gestohlen wurde. Dieser Loader ähnelt ein wenig der Implementierung der Methode when($.when), die sich auf das zurückgestellte Objekt bezieht ( $.Deferred) in jQuery;
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script> (function () { //存储已经加载好的模块 var moduleCache = {}; var define = function (deps, callback) { var params = []; var depCount = 0; var i, len, isEmpty = false, modName; //获取当前正在执行的js代码段,这个在onLoad事件之前执行 modName = document.currentScript && document.currentScript.id || 'REQUIRE_MAIN'; //简单实现,这里未做参数检查,只考虑数组的情况 if (deps.length) { for (i = 0, len = deps.length; i < len; i++) { (function (i) { //依赖加一 depCount++; //这块回调很关键 loadMod(deps[i], function (param) { params[i] = param; depCount--; if (depCount == 0) { saveModule(modName, params, callback); } }); })(i); } } else { isEmpty = true; } if (isEmpty) { setTimeout(function () { saveModule(modName, null, callback); }, 0); } }; //考虑最简单逻辑即可 var _getPathUrl = function (modName) { var url = modName; //不严谨 if (url.indexOf('.js') == -1) url = url + '.js'; return url; }; //模块加载 var loadMod = function (modName, callback) { var url = _getPathUrl(modName), fs, mod; //如果该模块已经被加载 if (moduleCache[modName]) { mod = moduleCache[modName]; if (mod.status == 'loaded') { setTimeout(callback(this.params), 0); } else { //如果未到加载状态直接往onLoad插入值,在依赖项加载好后会解除依赖 mod.onload.push(callback); } } else { /* 这里重点说一下Module对象 status代表模块状态 onLoad事实上对应requireJS的事件回调,该模块被引用多少次变化执行多少次回调,通知被依赖项解除依赖 */ mod = moduleCache[modName] = { modName: modName, status: 'loading', export: null, onload: [callback] }; _script = document.createElement('script'); _script.id = modName; _script.type = 'text/javascript'; _script.charset = 'utf-8'; _script.async = true; _script.src = url; //这段代码在这个场景中意义不大,注释了 // _script.onload = function (e) {}; fs = document.getElementsByTagName('script')[0]; fs.parentNode.insertBefore(_script, fs); } }; var saveModule = function (modName, params, callback) { var mod, fn; if (moduleCache.hasOwnProperty(modName)) { mod = moduleCache[modName]; mod.status = 'loaded'; //输出项 mod.export = callback ? callback(params) : null; //解除父类依赖,这里事实上使用事件监听较好 while (fn = mod.onload.shift()) { fn(mod.export); } } else { callback && callback.apply(window, params); } }; window.require = define; window.define = define; })(); </script> </head> <body> </body> </html>
Ein Beispiel
Ein kleines Beispiel schreiben, der Code ist einfach und kann von Experten ignoriert werden. Die Verzeichnisstruktur ist wie folgt:
Wir legen alle Ereignisse in controller/mainController.js ab,
define(["model/data","view/view0"],function(data, view) { var init = function() { var body = document.getElementsByTagName("body")[0]; var aBtn = document.getElementsByTagName("button"); for(var i=0; i< aBtn.length; i++) { aBtn[i].onclick = (function(i) { return function() { body.appendChild( view.getView(data[i]) ); }; })(i); }; }; return { init : init }; });
Alle Daten legen wir in model/data.js ab;
define(function() { return [ {name : "qihao"}, {name : "nono"}, {name : "hehe"}, {name : "gege"} ]; })
Der JS der Ansicht wird im Ansichtsverzeichnis abgelegt. view0.js ist hauptsächlich für die Generierung von HTML-Strings oder DOM-Knoten verantwortlich.
define(function() { return { getView : function(data) { var frag = document.createDocumentFragment(); frag.appendChild( document.createTextNode( data.name + " ") ); return frag; } } });
Der Eingang ist app.js Gleiches Verzeichnis wie load.html:
require(["controller/mainController"],function( controller ) { controller.init(); });
load.html Dies ist die Hauptschnittstelle:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title></head> <body> <button>0</button> <button>1</button> <button>2</button> <button>3</button> <script src="require.js" data-main="app.js"></script> </body> </html>
Das Obige ist JavaScript Für eine detaillierte Erklärung des Loader-Prinzips der modularen Programmierung, Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!

Die Auswahl von Python oder JavaScript sollte auf Karriereentwicklung, Lernkurve und Ökosystem beruhen: 1) Karriereentwicklung: Python ist für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet, während JavaScript für die Entwicklung von Front-End- und Full-Stack-Entwicklung geeignet ist. 2) Lernkurve: Die Python -Syntax ist prägnant und für Anfänger geeignet; Die JavaScript -Syntax ist flexibel. 3) Ökosystem: Python hat reichhaltige wissenschaftliche Computerbibliotheken und JavaScript hat ein leistungsstarkes Front-End-Framework.

Die Kraft des JavaScript -Frameworks liegt in der Vereinfachung der Entwicklung, der Verbesserung der Benutzererfahrung und der Anwendungsleistung. Betrachten Sie bei der Auswahl eines Frameworks: 1. Projektgröße und Komplexität, 2. Teamerfahrung, 3. Ökosystem und Community -Unterstützung.

Einführung Ich weiß, dass Sie es vielleicht seltsam finden. Was genau muss JavaScript, C und Browser tun? Sie scheinen nicht miteinander verbunden zu sein, aber tatsächlich spielen sie eine sehr wichtige Rolle in der modernen Webentwicklung. Heute werden wir die enge Verbindung zwischen diesen drei diskutieren. In diesem Artikel erfahren Sie, wie JavaScript im Browser ausgeführt wird, die Rolle von C in der Browser -Engine und wie sie zusammenarbeiten, um das Rendern und die Interaktion von Webseiten voranzutreiben. Wir alle kennen die Beziehung zwischen JavaScript und Browser. JavaScript ist die Kernsprache der Front-End-Entwicklung. Es läuft direkt im Browser und macht Webseiten lebhaft und interessant. Haben Sie sich jemals gefragt, warum Javascr

Node.js zeichnet sich bei effizienten E/A aus, vor allem bei Streams. Streams verarbeiten Daten inkrementell und vermeiden Speicherüberladung-ideal für große Dateien, Netzwerkaufgaben und Echtzeitanwendungen. Die Kombination von Streams mit der TypeScript -Sicherheit erzeugt eine POWE

Die Unterschiede in der Leistung und der Effizienz zwischen Python und JavaScript spiegeln sich hauptsächlich in: 1 wider: 1) Als interpretierter Sprache läuft Python langsam, weist jedoch eine hohe Entwicklungseffizienz auf und ist für eine schnelle Prototypentwicklung geeignet. 2) JavaScript ist auf einen einzelnen Thread im Browser beschränkt, aber Multi-Threading- und Asynchronen-E/A können verwendet werden, um die Leistung in Node.js zu verbessern, und beide haben Vorteile in tatsächlichen Projekten.

JavaScript stammt aus dem Jahr 1995 und wurde von Brandon Ike erstellt und realisierte die Sprache in C. 1.C-Sprache bietet Programmierfunktionen auf hoher Leistung und Systemebene für JavaScript. 2. Die Speicherverwaltung und die Leistungsoptimierung von JavaScript basieren auf C -Sprache. 3. Die plattformübergreifende Funktion der C-Sprache hilft JavaScript, auf verschiedenen Betriebssystemen effizient zu laufen.

JavaScript wird in Browsern und Node.js -Umgebungen ausgeführt und stützt sich auf die JavaScript -Engine, um Code zu analysieren und auszuführen. 1) abstrakter Syntaxbaum (AST) in der Parsenstufe erzeugen; 2) AST in die Kompilierungsphase in Bytecode oder Maschinencode umwandeln; 3) Führen Sie den kompilierten Code in der Ausführungsstufe aus.

Zu den zukünftigen Trends von Python und JavaScript gehören: 1. Python wird seine Position in den Bereichen wissenschaftlicher Computer und KI konsolidieren. JavaScript wird die Entwicklung der Web-Technologie fördern. Beide werden die Anwendungsszenarien in ihren jeweiligen Bereichen weiter erweitern und mehr Durchbrüche in der Leistung erzielen.


Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

Heiße Werkzeuge

SublimeText3 Englische Version
Empfohlen: Win-Version, unterstützt Code-Eingabeaufforderungen!

Sicherer Prüfungsbrowser
Safe Exam Browser ist eine sichere Browserumgebung für die sichere Teilnahme an Online-Prüfungen. Diese Software verwandelt jeden Computer in einen sicheren Arbeitsplatz. Es kontrolliert den Zugriff auf alle Dienstprogramme und verhindert, dass Schüler nicht autorisierte Ressourcen nutzen.

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Herunterladen der Mac-Version des Atom-Editors
Der beliebteste Open-Source-Editor

VSCode Windows 64-Bit-Download
Ein kostenloser und leistungsstarker IDE-Editor von Microsoft
