art*_*ung 348 javascript syntax jslint prefix-operator postfix-operator
++和 -
已知++(增量)和 - (减量)运算符通过鼓励过多的诡计来导致错误的代码.它们仅次于故障架构,可以实现病毒和其他安全威胁.有一个plusplus选项禁止使用这些运算符.
我知道像PHP这样的PHP结构$foo[$bar++]可能很容易导致一个错误,但是我无法找到一个更好的方法来控制循环而不是一个while( a < 10 ) do { /* foo */ a++; }或for (var i=0; i<10; i++) { /* foo */ }.
jslint是否突出显示它们是因为有些类似的语言缺少" ++"和" --"语法或者处理方式不同,还是有其他理由可以避免我可能会丢失的" ++"和" --"?
cdm*_*kay 398
我的观点是始终在一行中使用++和 - ,如:
i++;
array[i] = foo;
Run Code Online (Sandbox Code Playgroud)
代替
array[++i] = foo;
Run Code Online (Sandbox Code Playgroud)
除此之外的任何事情都可能让一些程序员感到困惑,在我看来并不值得.For循环是一个例外,因为增量运算符的使用是惯用的,因此总是清晰的.
Jon*_*n B 252
我坦率地对这个建议感到困惑.我的一部分想知道它是否与javascript编码器缺乏经验(感知或实际)有关.
我可以看到一个人如何"劈开"某些示例代码可能会在++和 - 中犯下一个无辜的错误,但我不明白为什么有经验的专业人士会避免它们.
Ecl*_*pse 69
在C中有一段历史,例如:
while (*a++ = *b++);
Run Code Online (Sandbox Code Playgroud)
复制一个字符串,也许这是他所指的过度欺骗的来源.
而且总是有什么问题
++i = i++;
Run Code Online (Sandbox Code Playgroud)
要么
i = i++ + ++i;
Run Code Online (Sandbox Code Playgroud)
实际上.它是用某些语言定义的,而在其他语言中则无法保证会发生什么.
抛开这些例子,我认为除了用于++递增的for循环之外,还有其他任何惯用语.在某些情况下,您可以使用foreach循环或者检查不同条件的while循环.但是扭曲你的代码以避免使用递增是荒谬的.
Nos*_*dna 46
如果您阅读JavaScript The Good Parts,您会看到Crockford在for循环中替换i ++ 是i + = 1(不是i = i + 1).这非常干净和可读,并且不太可能变成"棘手"的东西.
Crockford 在jsLint中禁止自动增量和自动减少选项.您可以选择是否遵循建议.
我自己的个人规则是不做任何与自动增量或自动减量相结合的事情.
我从C的多年经验中学到,如果我继续使用它,我就不会得到缓冲区溢出(或数组索引超出界限).但是我发现如果我陷入了在同一个声明中做其他事情的"过于棘手"的做法,我确实会得到缓冲区溢出.
因此,对于我自己的规则,使用i ++作为for循环中的增量是很好的.
Pau*_*tte 27
在循环中它是无害的,但在赋值语句中它可能导致意外的结果:
var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7
Run Code Online (Sandbox Code Playgroud)
变量和运算符之间的空格也会导致意外结果:
a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)
Run Code Online (Sandbox Code Playgroud)
在闭包中,意外的结果也是一个问题:
var foobar = function(i){var count = count || i; return function(){return count++;}}
baz = foobar(1);
baz(); //1
baz(); //2
var alphabeta = function(i){var count = count || i; return function(){return ++count;}}
omega = alphabeta(1);
omega(); //2
omega(); //3
Run Code Online (Sandbox Code Playgroud)
它会在换行后触发自动分号插入:
var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6
Run Code Online (Sandbox Code Playgroud)
preincrement/postincrement confusion可以产生非常难以诊断的错误.幸运的是,他们也完全没必要.有更好的方法可以将1添加到变量中.
参考
Eri*_*ric 17
请考虑以下代码
int a[10];
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;
int i = 0;
a[i++] = i++;
a[i++] = i++;
a[i++] = i++;
Run Code Online (Sandbox Code Playgroud)
因为i ++被评估两次输出(来自vs2005调试器)
[0] 0 int
[1] 0 int
[2] 2 int
[3] 0 int
[4] 4 int
Run Code Online (Sandbox Code Playgroud)
现在考虑以下代码:
int a[10];
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;
int i = 0;
a[++i] = ++i;
a[++i] = ++i;
a[++i] = ++i;
Run Code Online (Sandbox Code Playgroud)
请注意,输出是相同的.现在你可能会认为++ i和i ++是相同的.他们不是
[0] 0 int
[1] 0 int
[2] 2 int
[3] 0 int
[4] 4 int
Run Code Online (Sandbox Code Playgroud)
最后考虑这段代码
int a[10];
a[0] = 0;
a[1] = 0;
a[2] = 0;
a[3] = 0;
int i = 0;
a[++i] = i++;
a[++i] = i++;
a[++i] = i++;
Run Code Online (Sandbox Code Playgroud)
输出现在是:
[0] 0 int
[1] 1 int
[2] 0 int
[3] 3 int
[4] 0 int
[5] 5 int
Run Code Online (Sandbox Code Playgroud)
所以他们不一样,混合两者导致不那么直观的行为.我认为for循环可以用于++,但是当你在同一行或同一条指令上有多个++符号时要小心
Pau*_*ier 16
增量和减量运算符的"前"和"后"性质往往会使那些不熟悉它们的人感到困惑; 这是他们可能变得棘手的一种方式.
Sri*_*ram 16
在我看来,"明确总是比隐含更好".因为在某些时候,您可能会对此增量语句感到困惑y+ = x++ + ++y.一个好的程序员总是让他或她的代码更具可读性.
Han*_*rbe 14
避免++或 - 的最重要的基本原理是运算符返回值并同时引起副作用,使得更难以推断代码.
为了效率,我更喜欢:
我是Crockford先生的粉丝,但在这种情况下我不得不反对.++i将解析的文本减少25%,i+=1 并且可以说更清晰.
Stu*_*eld 13
我一直在观看道格拉斯·克罗克福德关于此的视频,他对不使用增量和减量的解释就是这样
首先,JavaScript中的数组是动态调整大小的,所以请原谅我,如果我错了,就不可能打破数组的界限并访问不应该在JavaScript中使用此方法访问的数据.
其次,如果我们避免复杂的事情,问题肯定不是我们有这个设施,但问题是那里有开发人员声称做JavaScript而不知道这些操作符是如何工作的?这很简单.value ++,给我当前值,然后在表达式中加上一个值,++ value,在给它之前递增值.
如果你只记得上面的内容,像++ ++ ++ b这样的表达式很容易解决.
var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3;
// a = 2 (equals two after the expression is finished);
// b = 2;
Run Code Online (Sandbox Code Playgroud)
我想你必须记住谁必须阅读代码,如果你有一个团队知道JS内部,那么你不必担心.如果没有,那么评论它,写不同,等等.做你需要做的.我不认为增量和减量本质上是坏的或产生错误,或者创建漏洞,可能根据您的受众而言可读性较低.
顺便说一下,我认为道格拉斯·克罗克福德无论如何都是一个传奇,但我认为他对一个不值得的运营商造成了很大的恐慌.
我活得被证明是错的......
Evg*_*vin 10
另一个例子,比其他一些简单返回递增值更简单:
function testIncrement1(x) {
return x++;
}
function testIncrement2(x) {
return ++x;
}
function testIncrement3(x) {
return x += 1;
}
console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1
Run Code Online (Sandbox Code Playgroud)
如您所见,如果您希望此运算符影响结果,则不应在return语句中使用后递增/递减.但是返回不会"捕获"后增量/减量运算符:
function closureIncrementTest() {
var x = 0;
function postIncrementX() {
return x++;
}
var y = postIncrementX();
console.log(x); // 1
}
Run Code Online (Sandbox Code Playgroud)
我认为程序员应该能够胜任他们使用的语言; 清楚地使用它; 并使用它.我不认为他们应该人为地削弱他们使用的语言.我是根据经验说的.我曾经在Cobol商店隔壁工作,他们没有使用ELSE,因为它太复杂了.Reductio ad absurdam.
| 归档时间: |
|
| 查看次数: |
315541 次 |
| 最近记录: |