阅读更多

29顶
20踩

Web前端

转载新闻 JavaScript 的死与生

2011-07-01 17:37 by 见习编辑 hotwind 评论(60) 有21177人浏览
JavaScript 的成功得益于在正确的时间出现在正确的地点。JavaScript 的兴起与浏览器的支持息息相关。你瞧,VBScript 就没这么好运气。

JavaScript 很流行,但它有先天缺陷。Brendan Eich 当初只花了 10 天时间就把 JavaScript 设计出来了,作为 JavaScript 之父,BE 如是说。

引用
与其说我爱 JavaScript,不如说我恨它。它是 C 语言和 Self 语言一夜情的产物。十八世纪英国文学家约翰逊博士说得好:“它的优秀之处并非原创,它的原创之处并不优秀。”(摘选自阮一峰的翻译:JavaScript 诞生记)


JavaScript 的不足,最明显之处是语法。

糟糕冗长的语法

可选参数和默认值
function(a, b, option) {
  option = option || {};
  // ...
}

上面的代码中,option 是可选参数,当没有传递时,默认值是 {}. 然而,传递的 option 值有可能是假值(falsy 值)。严格来写,得如下判断:
function(a, b, option) {
  option = arguments.length > 2 ? option : {};
  // ...
}


注意:option = typeof option !== 'undefined' ? option : {} 也有可能是错误的,因为传递过来的可能就是 undefined.

当不需要 b 参数,删除后,基于 arguments.length 的判断很容易导致忘记修改而出错:
function(a, option) {
  option = arguments.length > 2 ? option : {};
  // ...
}

如果能增加以下语法该多好呀:
function(a, b, option = {}) {
  // ...
}


Let

闭包很强大,也很恼火:
for (var i=0, ilen=elements.length; i<ilen; i++) {
  var element = elements[i];
  LIB_addEventListener(element, 'click', function(event) {
    alert('I was originally number ' + i);
  });
}

上面的代码经常在面试题中出现,解决办法是再包裹一层:
for (var i=0, ilen=elements.length; i<ilen; i++) {
  var element = elements[i];
  (function(num) {
    LIB_addEventListener(element, 'click', function(event) {
      alert('I was originally number ' + num);
    });
  }(i));
}

如果直接支持 let 语法该多好呀:
for (var i=0, ilen=elements.length; i<ilen; i++) {
  var element = elements[i];
  let (num = i) {
    LIB_addEventListener(element, function(event) {
      alert('I was originally number ' + num);
    });
  };
}


模块

模块模式是一种无奈的选择:
var event = (function() {

  // private variables
  var listeners = [];

  function addEventListener(f) {
    listeners.push(f);
  }

  function clearEventListeners() {
    listeners = [];
  }

  // ...

  // export the module's API
  return {
    addEventListener: addEventListener,
    clearEventListeners: clearEventListeners
    // ...
 };
}());


如果原生支持该多好呀:

module event {

  // private variables
  var listeners = [];

  export function addEventListener(f) {
    listeners.push(f);
  }

  export function clearEventListeners() {
     listeners = [];
  }

  // ...
}
(function() {

  import event;

  // ...
}());


继承

JavaScript 要通过原型链来实现继承:

function Employee(first, last, position) {
  // call the superclass constructor
  Person.call(this, first, last);
  this.position = position;
};
// inherit from Person
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

// define an overridding toString() method
Employee.prototype.toString = function() {
  // call superclass's overridden toString() method
  return Person.prototype.toString.call(this) +
         ' is a ' + this.position;
};


如果能写成下面这样该多好呀:

class Employee extends Person {
  constructor(first, last, position) {
      super(first, last);
      public position = position;
  }

  update(camera) {
      return super.update() + ' is a ' + position;
  }
}


感悟

ECMAScript 委员会已意识到 JavaScript 在语法层面上的不足。在 Harmony 规范中,以上所有语法均已提案。

我们什么时候才能使用以上语法呢?

只要有宏(Macro)

Lisp 语言的宏特性非常强大。通过宏,你可以根据自己的喜好定义想要的语法格式。宏特性使得 Lisp 成为一门“可编程的编程语言(the programmable programming language)”.

JavaScript 没有宏。给类 C 语言添加宏特性,目前依旧是个研究课题,很有难度。

只要有宏,我们就可以自定义语法。但 JavaScript 的宏特性遥遥无期,还是找找其他路子吧。

Harmony

Harmony 规范里的语法扩展,可能是我们所有人的梦。Harmony 有可能成为 ECMAScript 6 规范。在这之前,我们需要等待,耐心等待。

截止 2011 年 5 月,w3school 显示 IE6 的市场份额还有 2.4%. Net Market Share 显示 IE6 占有 10.36% 市场份额。还有 IE7 的市场份额也不少。这些老旧浏览器短期内不会退隐市场,对于商业公司来说,比如 Amazon,不可能放弃这批用户。糟糕的现状。(中国大陆更惨,IE6/7 还占有 40% 多市场份额)

我们不能寄期望于“IE 该死”这类呼吁来让用户升级。听到过一种说法:IE 用户仅会在更换电脑硬件时,才升级浏览器。悲催的是,对于普通用户来说,收收 email, 上上 Facebook, Twitter, 现有的硬件已足够。没有理由让他们去花一笔钱。

Goggle Apps 最近宣布,从 2011 年 8 月开始,将停止支持 IE7。

通过各种保守估计,Amazon 的网站开发者,用上 Harmony 语法扩展,要一直等到 2023 年!

风华正茂的你,愿意等待 10 多年后,再用上这些好用的语法吗?

JavaScript 已死

死因:分号癌。(semicolon cancer. 作者的调侃,意指语法导致 JavaScript 死去)

通过上面的分析可以看出,宏特性实现太难,Harmony 规范的实现则遥遥无期。大量程序员开始书写 JavaScript, 其中有很多人已经厌倦或开始厌倦 JavaScript 冗长糟糕的语法。我们需要新的语法,我们不想等待!JavaScript,作为源码编写语言,已经死了!

JavaScript 先生,你曾有过辉煌的统治。我们与你,有过甜蜜的回忆,一起产出过很多有趣的应用。祝福逝者安息。

JavaScript 长存

程序员喜欢掌控自己的命运。作为源码编写语言,JavaScript 已死。我们可以选择或创造另一种更好的源码语言,将其编译成 ECMAScript 3 的语法格式。

JavaScript 的新生,是作为编译目标(compilation target)。

编译成 JavaScript 的语言

能编译成 JavaScript 的语言有很多。我在 1997 年时,收集过一份列表。包括:
  • JavaScript 扩展语言:已死的 ECMAScript 4, Narrative Script, Objective-J.
  • 已存在的语言:Scheme, Common Lisp, Smalltalk, Ruby, Python, Java, C#, Haskell 等。
  • 还有一些崭新的语言:HaXe, Milescript, Links, Flapjax, 专门为 web 编程而设计。

在这些编译器项目中,Goggle 的 GWT Java-to-JavaScript 编译器有可能是最成功的一个。 然而悲剧的是,现实项目中,很少看到 GWT 的身影。原因如下:

1. 维护成本很高。编译器可能有 bug. 假设你在一个大型项目中,发现了编译器的一个 bug, 作为维护者,除了维护源码,你还得维护编译器。天哪,你有这个本事吗?你有这个本事,CEO 也不愿意花这个钱呀。

2. 调试麻烦。Firebug 报了一个错,报的是编译后的行号。老板站在你背后:赶快啦,小伙子!可是这该死的编译后代码,究竟对应哪一行源码呀?

3. 招聘不到人。假设你使用 Objective-J 开发一个项目,但人手不够。赶紧招人,HR 说 1000 个人里面,只有 100 个听说过 Objective-J, 另外 900 个只听说过 JavaScript. 结局是你每找一个新人,都得先培训一把,真是糟糕透顶。

虽然编译器有以上各种不是,但各种编译器依旧如雨后春笋大量涌现。毫无疑问,编写 JavaScript 编译器非常酷。给我报酬,我也想写一个。

在上面的编译器列表中,有一个非常有名的引起过很大轰动的:CoffeeScript. 我们来谈谈它。

CoffeeScript

为什么 CoffeeScript 如此火爆?我到现在为止也没想明白。是因为给空白赋予了意义,还是带箭头的函数语法?每念及此,我的胃就忍不住波涛汹涌。CoffeeScript 有很多新特性:default parameter values, rest parameters, spread, destructuring,fixing the whole implied global mess… CoffeeScript 很多特性是 Harmony 规范的一部分,有可能在未来浏览器中直接支持。CoffeeScript 能让人立刻满足。

@pyronicide 在 Twitter 上说:#coffeescript 支持函数默认参数值,这太令人兴奋了。

在 TXJS 2011 大会上,Douglas Crockford 也表示:CoffeeScript 无疑是个好东东。

CoffeeScript: Accelerated JavaScript Development 一书的作者说:

引用
@trevorburnham
[...] CoffeeScript 不是将 JS 变成 Ruby 或 Python, 而是通过一套语法,来更好地发挥 JavaScript 内在的优秀。


Douglas Crockford 认为 JavaScript 有好的方面,并开发了 JSLint 工具来保证开发者远离 JavaScript 中的糟粕。JSLint 允许的语法子集值得拥有自己的名字,我们不妨称之为 GoodScript.

ECMAScript 5 则引入了 "use strict" 指令来限制 with 等语法的使用。

CoffeeScript, GoodScript, ECMAScript 5 的目标是一致的:远离糟粕,同时提供有用的、安全的语言特性给你。

GoodScript 没有提供新特性,ECMAScript 5 的严格模式,大部分浏览器还不支持。然而,我们不想等待。

剩下的选择是 CoffeeScript. 好处:

特别适合 web 开发。这可能是其他 JavaScript 编译器没做或做得不好的地方。
CoffeeScript 对 JavaScript 的封装适度。这样能使得编译后的代码比较容易阅读,调试也就不那么困难了。

CoffeeScript 看起来就像是书写 JavaScript 代码的一套宏。

CoffeeScript 的编译器提供客户端版本。这样,使用者可以自由选择,开发者也可以快速开发新功能,而不受标准的局限。由社区的愿景和需求推动 CoffeeScript 的发展,这很不错。

发明自己的语言

你可以去做,这会是一个很好的练习。作为 JavaScript 编译器的开发者,将拥有无上荣耀。

发明自己的语言,危险之处在于:你认为最终你将比 JavaScript 做得更好。语言设计很难,我敢打赌你的语言很难扩大市场份额。CoffeeScript 尚未进入青春期,就已经有抱怨的声音了。

你可能会为自己的编译器能编译出简单、可读的代码而骄傲。可是,一碰到特殊情况,你就会郁闷得想撞墙。

你的语言里将会出现惯用法。接着,你马上会发现有人会破坏这些惯用法(除非你的语言刚好支持宏)。

风凉话就不多说了。立刻去开发自己的语言吧,你会成为一个很好的程序员。

作为编译目标语言,JavaScript 缺少什么?

作为编译目标语言,JavaScript 重获新生。在 JSConf.US talk 中,Brendan Eich 表示:Harmony 规范的目的是让 JavaScript 成为更好的编译目标。

编译后的 JavaScript 有可能比手写的 JavaScript 运行效率更低,这就和编译后的 C 有可能比手写的汇编语言效率更低一样。幸运的是,JavaScript 的瓶颈主要在 DOM 操作上,语言本身的效率损耗相对可以接受。虽然话是这么说,但一些高效的源码语言编译后,由于 JavaScript 本身的问题,可能极其低效,以致于无法在真实环境中使用。Harmony 规范中已经有部分特性能保证避免这类问题。

合理的尾部调用

function isEven(number) {
  if (number === 0) {
      return true;
  }
  else {
      return isOdd(number - 1);
  }
}

function isOdd(number) {
  if (number === 0) {
      return false;
  }
  else {
      return isEven(number - 1);
  }
}

isEven(100000); // InternalError: too much recursion


上面的代码,在目前的浏览器中运行,会堆栈溢出。

可以通过 蹦床(trampolines) 技巧来优化:
function bounce(ret) {
  while (typeof ret === 'function') {
      ret = ret();
  }
  return ret;
}

function isEven(number) {
  if (number === 0) {
      return true;
  }
  else {
      return function() {
          return isOdd(number - 1);
      };
  }
}

function isOdd(number) {
  if (number === 0) {
      return false;
  }
  else {
      return function() {
          return isEven(number - 1);
      };
  }
}
bounce(function() {return isEven(100000);}); // true


通过 bounce 方式,在运行 isOdd(99999) 时,isEven(100000) 已经完成并从堆栈中退出了,因此不会造成溢出。

幸运地是,ECMAScript Harmony 已经考虑到了这一点,会自动进行优化。这对程序开发者和编译器开发者都是有益的。

Lambdas

lambda 并不神奇。简言之,lambda 就是可调用的东西,比如 function, 但需要遵守 TCP(Tennent 一致性原则,Tennent’s Correspondence Principle)。TCP 要求:用一个紧邻的 lambda 对表达式或代码块进行封装,不会改变被封装的代码的含义。

很显然,JavaScript 的 function 不是 lambda:

function one() {
  return 1;
}

one(); // 1


封装后,返回值发生了变化:

function one() {
  (function() {
      return 1;
  }());
}

one(); // undefined


对于接受两个参数并将其求和的代码块,lambda 语法提议写成:{|a, b| a + b}

对于上面的例子,采用 lambda 封装将保证返回值和封装前一样:

function one() {
  ({||
      return 1;
  }());
}

one(); // 1


lambda 块的稻草人提案目前还没有提升到 Harmony 规范中,让我们一起努力吧。

浏览器缺少什么?

JavaScript 的兴衰存亡离不开浏览器。JavaScript 的新生,也需要浏览器的靠谱支持。

Mozilla 发起了一个 SourceMap 项目,这可以使得在调试编译后的代码时,能映射回源码的对应代码行。这太 cool 了,能极大的减少调试成本。

听说 Webkit 的小伙子们也在干同样的事情,可惜我找不到任何证据了-.-

通晓数种语言

JavaScript 在浏览器上的垄断,意味着前端程序员都会同一门语言。然而,编译器的差异性,会使得 CoffeeScript 程序员,很难立刻看懂基于 Traceur 的 JavaScript 代码。

这种分歧不可避免。比如有 C, 同时有 C++ 和 Objective-C 等各种语言。Java 也一样,基于 JVM 还可以选择 Clojure 或 JRuby. 微软意识到这一点,开发了 CLR. C#, Basic, IronPython 等都可以运行在 CLR 上。

前端中的沟通障碍并非新鲜事物。一个 Dojo 程序员,难以立刻明白基于 jQuery 或 YUI 的代码。

拥有多种源码书写语言会增加社区的沟通障碍。程序员仍需要了解 JavaScript. 至少一段时间内程序员还需要懂得 JavaScript. 但在短短几年后,他们可能会更了解其他源码语言。

总结

能有机会目睹 JavaScript 的新生,是件很棒的事情。在 JavaScript 编译的竞争中,很难说谁会最终赢得市场份额,但毫无疑问,这肯定会很有趣。如今,CoffeeScript 蓄势待发,但我相信许多其他成功的源码语言将接踵而至。

你的想法呢?

VIA  JavaScript is Dead. Long Live JavaScript!
来自: Starming
29
20
评论 共 60 条 请登录后发表评论
60 楼 12345678 2012-04-13 15:37
白天不能说坏话呀,不然你就成为反驳的对象~
59 楼 jkxydp 2011-10-13 11:32
javascript的缺点正是它的优点,往往怪脾气的人鬼点子多,能出人意料地解决难题,这就是javascript。
58 楼 hastune 2011-10-12 10:26
语言仅仅是为了创造程序而已。去其糟粕,用其精华。拿糟粕说事,没什么意义。
57 楼 jj7jj7jj 2011-07-29 11:08
js也是经历过风雨的,淘汰大权独揽的ie脚本(vbscript,jscript),经历过无数的web变革依然存在,这种存在是有理由的,不是任何一个山寨script所能取代的,看了几篇文章就谈生与死,这种说法是不负责任的,js作为web端的王者就是他的特质,包括他的优点和缺点
56 楼 jj7jj7jj 2011-07-29 10:32
我同意xhs10195的观点,有些人的水平确实不足以谈封装和模块~
55 楼 arthas777 2011-07-27 00:43
xhs10195 写道
这篇也是一家之言,作为开发人员,我还是喜欢最原始的代码。当然像jquery这样强大的工具就宁当别论了。会编程的人也不要有事没事,就想着封装这封装那的,离原始代码越远,越垃圾。最讨厌封装来封装去的框架,有必要这么绕嘛。

哥们,你知道封装的意义是什么吗?
哥们,你又知道模块的意义是什么?
54 楼 xhs10195 2011-07-25 14:25
竟然有人谈论javascript的死与生,太嚣张了。javascript可是获得这么多开发人员认可的。等你能开发出比javascript更流行的语言再来发表吧。现在有点舌燥了。
53 楼 zhengjie_dna 2011-07-25 14:21
lambda
JJiaoWzk 写道
inshua 写道
moonlitsky 写道
封装后,返回值发生了变化:

Javascript代码
function one() { 
  (function() { 
      return 1; 
  }()); 

 
one(); // undefined 

各位不觉得这段代码有问题吗?



就是,我正要說,它沒有 return

没什么问题,本身就是封装一层,看前面lamba封装后不改变封装前代码的功能那段,加上return就不是单单封装一下了吧

.......看着你的应用我就想笑麻烦你看清楚点
52 楼 xhs10195 2011-07-25 14:18
这篇也是一家之言,作为开发人员,我还是喜欢最原始的代码。当然像jquery这样强大的工具就宁当别论了。会编程的人也不要有事没事,就想着封装这封装那的,离原始代码越远,越垃圾。最讨厌封装来封装去的框架,有必要这么绕嘛。
51 楼 xiangtaoiphone 2011-07-22 15:32
成事不足败事有余
50 楼 zhangxpower 2011-07-22 15:26
本人坚信 js不会死,到头来 只会支持越来越多的功能,越来越强大。 因为它已逐步走向成熟.并在JSCRIPT类语言中脱颖而出.
49 楼 wgh369 2011-07-20 15:55
写web的程序员没一个不恨JS的,就是没的选,只有这破东西
48 楼 未来软件 2011-07-20 12:05
给我一个,可以代替Javascript的语言;Javascript就可以死了;适者生存,不适应者,淘汰!!!理由在那?新的语言是什么?理由...只发现Javascript它的弊端,那另一个代替的在那?
47 楼 liangoogle 2011-07-20 11:19
太多人用js了,想死都不容易!
46 楼 zhidde 2011-07-19 11:27
ie6在国内都能再活个四五年,别说js了
45 楼 ahead_zhan 2011-07-18 15:13
JS已经引发了这么多的应用及开源库
忽然之间,还没有脚本能够替代JS
44 楼 dearplain 2011-07-18 13:48
说得好啊,一个好的设计能大大减轻程序员负担,但是现在的语言除了动态语言和静态语言之外没有太大区别,这是由于计算机的本质决定的,能用就好了,当然,以后动态语言会比静态语言发展快。。
43 楼 Jacky-Q 2011-07-18 11:40
浏览器还没死呢,js怎么死?
42 楼 luohuijun619 2011-07-18 09:18
javaScript还是很不错啦,现在有很多基于JS的框架,比如Ext,Dojo,jquery……
41 楼 ccxw1983 2011-07-17 22:16
javascript用的好好的,无所谓了,为了懒得学javascript而用其他途径是脑子进水了。

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Jasper report fond 粗体不显示问题解决

    refer to http://mdahlman.wordpress.com/2010/05/28/jaspersoft-v3-7-font-extensions/ 粗体形式在ireport 显示正常,但是exported pdf report ,不能显示粗体 总结如下: 1.在 ireport install 你需要的字体 , following 以上文章里的步骤 2.

  • 【经验分享】使用MindStudio进行RotatE模型开发

    本文详细介绍了MindSpore深度学习框架的环境搭建和配置介绍、MindStudio开发平台的安装与使用、RotatE模型的介绍与迁移、使用MindStudio进行训练评估与导出、MindInsight性能分析。

  • JasperReport的应用,从模块设计到JAVA调用,中文问题...

    安装 &nbsp;&nbsp;到官网下载社区版 先解决中文问题 &nbsp;&nbsp;中文问题一直需要我们人手处理, 真是够了, 所以第一时间处理: 先在设置里面打开jaspersoftware-studio-&gt;fonts,建立 雅黑字体 然后,点击Export导出为jar, 放到项目的lib文件夹里面 新建Report &nbsp;&nbsp; &nbsp;&nbsp;因为要用java提供数据源,所以这里选 加入两个参数,一会从java传入 定义fields 然后逐个field拖到de.

  • 编写一个Java Web项目,实现从properties文件读取数据存储到数据库,并从数据库中读取数据,将结果显示在页面上。启动mysql数据库服务器端,并且创建一个名为studentinfo的数据库

    现在是2021年04月26日11:05:08 ,趁今天有空把它搞完. 这里呢采用德鲁伊连接池哈 记得导包 1先上效果图 2上截图 点击删除2 3代码共享 dataOperation.jsp &lt;%-- Created by IntelliJ IDEA. User: zhangxu Date: 2021/4/26 Time: 10:32 上午 To change this template use F...

  • Jasper报表使用扩展字体与字体加粗

    使用JasperSoft Studio编辑报表模板时,使用到了扩展的字体(特殊字体),在JAVA的工程上,需要做字体定义处理。 在Resources下增加 jasperreports_extension.properties 文件,在文件内配置字体的参数(字体配置文件) net.sf.jasperreports.extension.registry.factory.simple.font.f...

  • Jaspersoft报表学习

  • jasperreports导出pdf报表时粗体的显示问题

    最近一直在做报表,用的是iReport3.7.3和jasperReport3.7.3,在导出pdf形式的报表时,文字的粗体效果出不来,弄了大半天,查阅了很多资料,试了很多种方法,效果都不理想。下面总结一下:1.修改jasperreports-3.7.3.jar包的JRPdfExporter的源码这种方法网上到处都是,但我没试过,不知道是否可行,因为我反编译出来的源码有大量的错误,下载的一个编译器也...

  • Jaspersoft 环境搭建和入门简单实例

    JasperReport简介 JasperReport是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。JasperReport是开源的,对于开发者来说是个不错的选择。 JasperReport开发环境搭建 第一步:下载Ja...

  • Jaspersoft使用教程

    Jaspersoft:这是基于Eclipse软件开发的图形化报表设计工具。

  • JasperReport detail 分栏展示

    JasperReport detial分栏展示使用示例

  • 可用的ss-mongo框架的pom.xml及相关的web.xml等

    pom.xml web.xml strust.xml common.xml

  • JasperReport 根据内容动态调整报表行高

    JasperReport结合IReport如何设计出一个能根据内容自动调整行高的报表呢?   有人说目前只有detail 这个Band才可以实现。其实无论哪个band都可以实现这个功能! 主要是通过以下几个元素实现: 1.Stretch with overflow 针对TextFileld 2.Stretch Type:relative to tallest object/relativ...

  • iReport报表Detail设置自适应高度

    1.报表的Pint Order=Verticl 2.Detail Band选中后,Spli Type=Stretch 3.选中textField就是所有希望自适应高度的数据,属性里 Stretch With Overflow选中。 Stretch type,默认是No Stretch,改成Relative To Band Height. 大功告成炎哥牛逼 ...

  • java jasperReports导出PDF字体加粗失效,中文显示不出来

    最近搞了一个项目,需要生成投保电子凭证的pdf文件,之前在项目也用了这个组件,只是很多年前别人开发的,我只是项目负责人而已,想起以前的项目就找了ireport这个做为生成pdf的工具。一开始捣鼓了好久,中午不显示出来,加粗问题困扰很久,终于两天时间把的设计完,主要是模板改的版本太多,其实这个东西真的挺简单的。不多说了,直接上代码。 &lt;!-- jasperreports Start --&...

  • java中style的用法

    在前面的两个单元里我们学习了基本的HTML Tag并且了解了HTML Tag可以有属性。有些Tag,比如说, Tag等必须使用属性。属性的存在让HTML Tag更有活性,功能更强大!在这一单元里,我们着重介绍一个很有用的属性——style。 其实,在上一单元中,我们谈到了style的属性。可以用它来对文字进行修饰,包括颜色,大小,位置等等。因为几乎所有的HTML Tag都可以使用style

  • JasperReport实现字体部分加粗

    使用工具 TIBCO Jaspersoft Studio-6.19.0使用text field来实现。同理,加下划线,空行也是如此。 效果图

  • JasperReport动态页面的设置

    使用工具为 TIBCO Jaspersoft Studio-6.19.0JasperReport实现动态报表主要分为几个方面。 1、元素高度的动态变化,也就是字数过多时候,会自动往下移动。 2、位置的动态变化,当高度是动态的时候,高度的动态变化也是必然需要的。 3、动态显示某个区域的问题,例如当没有优惠券的时候,我们是不需要显示优惠券这一块区域的。 接下来我会进行说明。在使用Parameters去接收参数的时候,我们不确定输入的参数长度是多少,这样子我们就需要去动态的调整高度,以让内容全部显示出来。默认的我

Global site tag (gtag.js) - Google Analytics