#ifndef 在 JavaScript 中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7376131/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
#ifndef in javascript
提问by KenEucker
I am looking for a solution to only define a function once in Javascript using something exactly like #ifndef in compiled languages. I found a couple of libraries that were supposed to mimic this functionality but they didn't work.
我正在寻找一种解决方案,在 Javascript 中使用与编译语言中的 #ifndef 完全一样的东西只定义一次函数。我发现了一些应该模仿此功能的库,但它们不起作用。
I am working with MVC 3 Razor and have defined some html helpers do put what are essentially user controls onto the page.
我正在使用 MVC 3 Razor 并定义了一些 html 帮助程序将本质上是用户控件的内容放到页面上。
Each control has a set of javascript functions that define specific functionality for that control, so herein lies the issue: the functions get defined multiple times when the helper is called multiple times on a single page.
每个控件都有一组 javascript 函数来定义该控件的特定功能,所以这里存在一个问题:当在单个页面上多次调用帮助程序时,这些函数会被多次定义。
I am hoping to find a way to keep the very small amount of javascript defined within the helper and not have to divide all of the javascript for each of these small helpers in a separate file.
我希望找到一种方法来保留在 helper 中定义的非常少量的 javascript,而不必将这些小助手的所有 javascript 划分到单独的文件中。
Sample:
样本:
@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 doesn't work in the browser, if gives me the error: '48: Unrecognized token ILLEGAL'
以上在浏览器中不起作用,如果给我错误:'48: Unrecognized token ILLEGAL'
回答by jfriend00
As I presume you know, Javascript doesn't have preprocessor directives like C/C++, but you can use regular if
statements that are evaluated at run-time like this:
我想你知道,Javascript 没有像 C/C++ 这样的预处理器指令,但你可以使用if
在运行时评估的常规语句,如下所示:
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 your concern is just that you have multiple copies of the exact same function names in the library that each control uses, that isn't technically a problem in Javascript. The last defined one will be the operative one, but if they're all the same that isn't technically a problem. Only one definition will exist in memory as the later definitions will replace the earlier ones.
如果您只是担心每个控件使用的库中有多个完全相同的函数名称的副本,那么这在 Javascript 中从技术上讲不是问题。最后定义的将是可操作的,但如果它们都相同,那么这在技术上不是问题。内存中将只存在一个定义,因为后面的定义将替换前面的定义。
If you control the source of the controls, then it would be better to break the common utilities out separately into their own JS file and have the host page just include that utilities script file once.
如果您控制控件的来源,那么最好将通用实用程序单独分解为它们自己的 JS 文件,并使主机页面只包含该实用程序脚本文件一次。
Or (with a little more work but no additional responsibilities for the host page), each control could dynamically load their utlities from an external JS file and check a known global variable to see if some other control has already loaded the common external JS.
或者(需要做更多的工作,但对宿主页面没有额外的责任),每个控件都可以从外部 JS 文件动态加载它们的实用程序,并检查一个已知的全局变量以查看其他控件是否已经加载了通用的外部 JS。
回答by Max
If you have some build script I suggest to use GPP preprocessor(http://en.nothingisreal.com/wiki/GPP, or win version http://makc.googlecode.com/svn/trunk/gpp.2.24-windows/)
如果您有一些构建脚本,我建议使用 GPP 预处理器(http://en.nothingisreal.com/wiki/GPP,或 win 版本http://makc.googlecode.com/svn/trunk/gpp.2.24-windows/)
So you need to do the following steps:
因此,您需要执行以下步骤:
- gpp -o _script.js script.js(where _script.js - your source file with preprocessor commands)
- (OPTIONAL) minify script.js (using google closure compiler, etc.)
- deploy script.js to your web folder.
- gpp -o _script.js script.js(其中 _script.js - 带有预处理器命令的源文件)
- (可选)缩小 script.js(使用谷歌闭包编译器等)
- 将 script.js 部署到您的 web 文件夹。
In this case you'll get the most optimized js code. And you do not need runtime checks
在这种情况下,您将获得最优化的 js 代码。而且您不需要运行时检查
#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
回答by Sesha Kiran
I see that that the answer provided by jfriend is a bit old when node.js is not around. Pls. check the latest preprocessor.js (available through npm install).
我看到当 node.js 不在时,jfriend 提供的答案有点旧。请。检查最新的 preprocessor.js(可通过 npm install 获得)。
You can use the static conditions like below (from documentation)
您可以使用如下静态条件(来自文档)
// #ifdef FULL
console.log("Including extension");
// #include "path/to/extension.js"
// #else
console.log("Not including extension");
// #endif
Usage is :
用法是:
Usage: preprocess sourceFile [baseDirectory] [-myKey[=myValue], ...] [> outFile]
preprocess Source.js . -FULL=true > Source.full.js
回答by aMarCruz
Old theme, but for anyone interested in the required solution I wrote jspreprocto deploy some riot modules, all in JavaScript for node 0.10.0 and above.
旧主题,但对于任何对所需解决方案感兴趣的人,我编写了jspreproc来部署一些 riot 模块,所有模块都在 JavaScript 中用于节点 0.10.0 及更高版本。
jspreproc is open source, remove empty lines, supports filters for preserve comments of different types, and conditional comments in C-style:
jspreproc 是开源的,去除空行,支持过滤器保留不同类型的注释,以及 C 风格的条件注释:
#if, #elif, #else, #endif
with expression anddefined()
support#define
with expression and basic macro-replacement#ifdef, #ifndef
#include, #include_once
#if, #elif, #else, #endif
有表达和defined()
支持#define
带表达式和基本宏替换#ifdef, #ifndef
#include, #include_once
Installation and usage example:
安装和使用示例:
$ npm -g i jspreproc
$ jspp -D RELEASE --empty-lines 0 lib/file1.js lib/file2.js > dist/app.js
Read more at the jspreproc repositoryon github.
在 github上的jspreproc 存储库中阅读更多信息。
回答by technosaurus
This is an old question but the answers are now a bit out of date. If you are trying to get better inlining or eliminate dead code you can use google's closure compileralong with the /** @const */
helper
这是一个古老的问题,但现在的答案有点过时了。如果你想更好地内联或消除死代码,你可以使用谷歌的闭包编译器和/** @const */
助手
Here is a completely random (useless except for demo) example of @const helper at work with advanced optimizations:
这是@const helper 使用高级优化的完全随机示例(除演示外无用):
/** @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]);
编译为: 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());
或没有@const:var a=!0;function b(){if(!a)var c=document;return c.getElementsByTagName("body")[0]}alert(b()+"New user"+b());
The benefit of this is that the code will still work during development without having to preprocess it before each run. (with the added benefit of better optimization)
这样做的好处是代码在开发过程中仍然可以工作,而无需在每次运行之前对其进行预处理。(具有更好优化的额外好处)
回答by Nick
回答by Ajay Surve
Its not possible to use Preprocessor or #define function inside JavaScript... JavaScript is loosly coupled and interpreted language..... But you can use this in Typescript as it is Strongly coupled and uses compiler...
它不可能在 JavaScript 中使用预处理器或 #define 函数...... JavaScript 是松耦合和解释性语言......但是你可以在 Typescript 中使用它,因为它是强耦合并使用编译器......