竟然有这么变态的语言,函数之间居然可以私通

pgmsoul 2012-08-30 02:53:40
今天用到JavaScript语言, 被这种语言的规则震惊了.


function a(){
for(i=0;i<10;i++){};
}
var i = 5;
a();
document.writeln(i);//输出居然是10, 也就是说, 函数内部的i其实就是全局这个i. 变态的是, JavaScript有很多内置全局变量,再加上自己使用的, 这局部变量如果不声明的话, 你知道哪个就和全局变量相同了. 可是JavaScript居然就不要求变量需要声明.


还有更变态的.

function a(){
for(i=0;i<20;i++){
}
}
function b(){
for(i=0;i<3;i++){
a();
}
return i;
}
document.writeln(b());

你猜输出是啥? 居然是21 ,合着这个i是可以大家一起用的呀. 可是如果你直接输出i,居然还说, 变量未定义, 不同函数共用局部变量, 但是函数外部不可以用, 这不是典型的私通吗? 明明底下通着呢, 还不能在公开场合说.
...全文
275 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
kllll1119 2012-08-31
  • 打赏
  • 举报
回复
很奇怪吗
就想叫yoko 2012-08-31
  • 打赏
  • 举报
回复
没啥问题吧。
只要规则是固定的就行了。
与C比较,用不同的写法可以实现相同的功能就行。
pgmsoul 2012-08-31
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

很奇怪吗
[/Quote]
当然奇怪了, 比如写字, 是从左向右, 因为右手拿笔, 从右向左会挡住刚写过的子, 还有从下往上写, 如果定这样的规则你不觉得奇怪吗?

规则不是乱定的.

其实每次, 只要是质疑的观点, 都有一群人在那里维护, 什么都是不完美的, 这是JavaScript一个很明显的缺陷, 只不过考虑到兼容性, 这种语法不太可能改了.

C和C++的规则也未必就是完美的, 如果让当初设计他的那些人重新设计的话, 应该有很多改进, 但是同样的, 考虑到兼容性, 广大的用户, 规则不管好不好都不能随便改了. 但是这不代表, 就不能说某个特性设计有缺陷.

JavaScript是一个非常匆忙的设计, 它有很多内在bug, 但是同样, 他也有很多的优点, 所有它会流行, 为什么不能说一下这种非常明显的设计失误呢?

你倒说说, 默认的全局变量有什么好处, 你再举个例子, 哪种语言, 默认的变量是全局的. 如果它这么设计好, 为什么别的语言不采用.
pgmsoul 2012-08-30
  • 打赏
  • 举报
回复
"use strict";

新特性, 很好. 这也说明我的观点, 还是有点道理的.
mujiok2003 2012-08-30
  • 打赏
  • 举报
回复
动态语言一般都是这样的,不需要先声明后使用。但是作用域还是需要。

顺便说一下,问错地方了吧?
zhanshen2891 2012-08-30
  • 打赏
  • 举报
回复
“私通”,呵呵~
www_adintr_com 2012-08-30
  • 打赏
  • 举报
回复
写成
function a(){
for(var i=0;i<20;i++){
}
}
就 OK 了.


function a(){
for(i=0;i<10;i++){};
}
var i = 5;
a();
document.writeln(i);/
这个这没有什么好惊奇的, 在 C++ 里也是一样的结果啊.
函数里没有定义这个变量, 全局又有这个变量, 自然使用的就是全局变量. 不同的是 C++ 是静态的, 编译之前就要知道那个全局变量. JavaScript 是动态的, 运行的时候能找到就行了.


function a(){
for(i=0;i<20;i++){
}
}
function b(){
for(i=0;i<3;i++){
a();
}
return i;
}
document.writeln(b());

直接输出不可用是因为还没有定义这个全局变量. 你调用一次 a(); 然后在输出 i 就有了. 还是因为 JavaScript 是动态语言, 你在函数里面定义了一个全局变量, 在你还没有调用这个函数之前, 全局变量就还没有创建. 你调用一次函数这个全局变量才创建.
龙哥依旧 2012-08-30
  • 打赏
  • 举报
回复
@#$%^()_)(*@#$()+_(&*^())_+_)(^^%
lucky-lucky 2012-08-30
  • 打赏
  • 举报
回复
每次在a函数中i都初始化为了0,a函数执行完后i都为20,再执行一次b函数for循环的自增,结果为21
pathuang68 2012-08-30
  • 打赏
  • 举报
回复
这个在javascript里面是很正常滴。
jngd 2012-08-30
  • 打赏
  • 举报
回复
你敢不敢加一句下面的语句??


"use strict";


另外:NotePad++里面有个插件叫做JsLint,你如果把JsLint的所有告警全部清除了,就没有这些莫名其妙的问题了。
jngd 2012-08-30
  • 打赏
  • 举报
回复
你敢不敢加 一句下面的代码?


"use strict";


另外 notepad++有个插件JsLint,你把JsLint的告警全部清除了,就没有这些莫名其妙的问题了。
pgmsoul 2012-08-30
  • 打赏
  • 举报
回复
未声明就是全局变量, 但是JavaScript必须执行一次函数才有让这样的变量被创建. 看人家PHP, 不显示声明, 函数内部都不能使用全局变量.

开始不知道, 一个函数写好了,测试好了(内部用了i做for循环).后来在另一个函数里掉, 居然莫名其妙的问题. 才发现这个规则, 局部变量一定要声明, 不然就是全局的.
Defonds 2012-08-30
  • 打赏
  • 举报
回复
JavaScript 还是满强大的。
Corner 2012-08-30
  • 打赏
  • 举报
回复
javascript能让你震惊的地方多着呢,它还可以动态修改内置类呢。想象一下,我在我的代码里给string类增加个函数(不修改string类源代码)~~
pgmsoul 2012-08-30
  • 打赏
  • 举报
回复
JavaScript还是有很多精华, 但是这个规则确实不太合适, 无需声明其实真不是个好规则, 声明一下真没什么麻烦的, 强制声明非常有必要. 但是无需声明, 好像是脚本语言的通用规则, 以至于需要声明的时候, 像PHP居然没有关键字, 所以只能用赋值语句代替. 再后来引入类的定义后, 又不得不加了个var关键字, 但是仅限于类定义, 估计早先的解释器懒得改了.

既然不需声明, 但是又不能直接使用, 比如writeln(i), 如果i未定义是不行的, 直接使用i++也是不行的. 本质上 是用赋值语句代替声明, 声明这一步是不能省的.

VB做了个坏榜样, 但是VB有强制声明选项, VB把后来者都带沟里了.

65,197

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧