#ifndef in javascript

I am looking for a solution to define a function only once in Javascript, using something like #ifndef in compiled languages. I found several libraries that were supposed to simulate this functionality, but they did not work.

I work with MVC 3 Razor and defined some html helpers that put user controls on the page.

Each control has a set of javascript functions that define specific functions for this control, so in this case there is a problem: the functions are defined several times when the helper is called several times on the same page.

I hope to find a way to save a very small amount of javascript defined in the helper, and should not share all javascript for each of these small helpers in a separate file.

Example:

@helper CmsImage(int id) { var Html = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; <text> <input type="button" class="editor_function" style="display: none;" onclick="editImage(@id); return false;" /> <script> function editImage(id) { $('#alt_text' + id).attr('value', $('#' + id).attr('alt')); $('#image_url' + id).attr('value', $('#' + id).attr('src')); } function saveImage(button, id) { $(button).parent().parent().removeClass('color-yellow').addClass('color-red'); $(button).parent().siblings('div.widget-content').html('<img alt="' + $('#alt_text' + id).val() + '" src="' + $('#image_url' + id).val() + '" id="' + id + '" />'); } #endif </script> Image Url: <input type="text" id=" image_url@ {id.ToString();}" /><br /> Alt Text: <input type="text" id=" alt_text@ {id.ToString();}" /><br /> <input type="button" value="save" onclick="saveImage(this, @{id.ToString();});" /> @Html.Raw(GetCurrentContent(id)) </text> } 

The above does not work in the browser if it gives me an error: '48: Unrecognized token ILLEGAL '

+8
source share
7 answers

I suppose you know that Javascript does not have preprocessor directives like C / C ++, but you can use regular if , which are evaluated at runtime as follows:

 if (typeof myFunc === "undefined") { var myFunc = function(a,b) { // body of your function here } } 

or for a whole library of functions:

 if (!window.controlUtilsDefined) { window.controlUtilsDefined = true; // put control library functions here function aaa() { // body here } function bbb() { // body here } } 

or if you want to check based on some other variable:

 var myFunc; if (debugMode) { myFunc = function(a,b) { // body of your function here } } else { myFunc = function(a,b) { // body of your alternate function here } } 

If you are worried that you have multiple copies of the same function names in the library that each control uses, which is not technically a problem in Javascript. The last one defined will be operational, but if they are all the same, that is technically not a problem. There will be only one definition in memory, since later definitions will replace earlier ones.

If you control the source of the controls, then it would be better to split the common utilities separately into your own JS file and include only this script utility file on the host page.

Or (with a bit more work, but without additional responsibilities for the main page), each control could dynamically load its utlities from an external JS file and check a known global variable to see if any other control loaded a common external JS .

+12
source

If you have a build script, I suggest using the GPP preprocessor ( http://en.nothingisreal.com/wiki/GPP or win the version http://makc.googlecode.com/svn/trunk/gpp.2.24-windows/ )

So, you need to take the following steps:

  • gpp -o _script.js script.js (where _script.js is your source file with the command preprocessor)
  • (OPTIONAL) minify script.js (using google close compiler, etc.)
  • expand script.js into your web folder.

In this case, you will get the most optimized js code. And you don't need runtime checks

 #define debugMode #ifdef debugMode var myFunc = function(a,b) { // body of your function here } #else var myFunc = function(a,b) { // body of your alternate function here } #endif 
+8
source

I see that the answer provided by jfriend is a little old when node.js does not exist. Pls. check out the latest .js preprocessor (available through an npm install).

You can use static conditions as shown below (from the documentation)

  // #ifdef FULL console.log("Including extension"); // #include "path/to/extension.js" // #else console.log("Not including extension"); // #endif 

Using:

 Usage: preprocess sourceFile [baseDirectory] [-myKey[=myValue], ...] [> outFile] preprocess Source.js . -FULL=true > Source.full.js 
+5
source

This is an old question, but the answers are now a bit outdated. If you are trying to improve nesting or eliminate dead code, you can use the google close compiler with the assistant /** @const */

The following is an example of a random (useless, except for demo) example of the @const helper when working with advanced optimizations:

 /** @const */ var G=true if(G){var d=document} function dummy(){if(!G){var d=document}return d.getElementsByTagName("body")[0]} function hello(name) { alert(dummy() + name + dummy()); } hello('New user'); 

compiles to: alert((void 0).getElementsByTagName("body")[0]+"New user"+(void 0).getElementsByTagName("body")[0]);

or without @const: var a=!0;function b(){if(!a)var c=document;return c.getElementsByTagName("body")[0]}alert(b()+"New user"+b());

The advantage of this is that the code will work during development without preprocessing before each run. (with the added benefit of better optimization)

+2
source

An old topic, but for anyone interested in the required solution, I wrote jspreproc to deploy some riot modules, all in JavaScript for node 0.10.0 and higher.

jspreproc is open source, removes empty lines, supports filters for saving comments of various types and conditional comments in C style:

  • #if, #elif, #else, #endif with expression and defined() support
  • #define with expression and basic macro substitution
  • #ifdef, #ifndef
  • #include, #include_once

Installation and use example:

 $ npm -gi jspreproc $ jspp -D RELEASE --empty-lines 0 lib/file1.js lib/file2.js > dist/app.js 

Read more at the jspreproc repository on github.

+2
source

Nowadays, it looks like work for RequireJS or the equivalent AMD module. All other answers speak of precompilation and minimization, which are good and should be taken into account additionally.

+1
source

It is not possible to use the preprocessor function or #define inside JavaScript ... JavaScript is a poorly coupled and interpreted language ..... But you can use this in Typescript, as it is highly related and uses a compiler ...

0
source

Source: https://habr.com/ru/post/897068/


All Articles