第三章 语句和表达式

时间:2020-12-15 00:09:58   收藏:0   阅读:38

语句和表达式

花括号的对齐方式

块语句间隔

switch语句

缩进

case语句的“连续执行”

“执行完一个case后连续执行下一个case”,这是否是一种广被认可的实践,但也是倍受争议的一个问题。不小心省略case末尾的break是很多bug的罪魁祸首,因此Douglas Crockford提出所有的case都应当以break、retur或throw做结尾,有很多人认为case的连续执行是一种可以接受的编程方法,只要程序逻辑非常清晰即可

switch(condition) {
    
    // 明显的依次执行
    case "first":  
    case "second":
        // 代码
        break;
        
    case "third":
        // 代码
       
        /* fail through */
    
    default: 
        // 代码
}

这段switch语句中,有两个明显的“连续执行”,程序执行完成第一个case后会继续执行第二个case,我们认为这种逻辑是合理的。因为第一个case语句中并没有需要执行的语句,也没有任何其他语句将这两个case语句分割开

第二个例子是case "third"执行后继续执行default里的逻辑。这个过程已经在注释中明确说明了,这是程序编写者故意为之。这段代码由于加了注释,我们可以清晰地看到case语句何时继续执行

default

switch语句另一个需要讨论的议题是,是否需要default。很多人认为不论何时都不应该省略default,哪怕default什么也不做。

switch(condition) {
    case "first":
        // 代码
        break;
        
    case "second":
        // 代码
        break;
    
    default: 
        // default中没有逻辑
}

作者更倾向于在没有默认行为的且写了注释情况下省略default

switch(condition) {
    case "first":
        // 代码
        break;
        
    case "second":
        // 代码
        break;
     
    // 没有default
}

with语句

with语句可以更改包含的上下文解析变量的方式。通过with可以用局部变量和函数的形式来访问特定的对象的属性和方法,这样就可以将对象前缀统统省略掉。如果一段代码重书写了很多对象成员,则可以使用with语句来缩短这段代码。例如:

var book = {
    title: "可维护的JavaScript",
    author: "Nicholas C. Zakas"
};

var message = "The book is ";

with (book) {
    message += title;
    message += " by " + author;
}

在这个例子中,with语句花括号内的代码中的book的属性都是通过局部变量来读取的,以增强标识符的解析。问题是我们很难分辨title和author出现在哪个位置,也很难分辨出message到底是局部变量还是book的一个属性。实际上这种困惑对开发者的影响更甚,JavaScript引擎和压缩工具无法对这段代码进行优化,因为它们无法猜出代码的正确含义。

在严格模式下,with是被明令禁止的,如果使用就会报语法错误

for循环

for循环有两种可以更改循环的执行过程(除了使用return和throw语句)。

break

第一种方式是使用break语句。不管所有的循环迭代又没有执行完毕,使用break总是可以立即退出循环。

var values = [1, 2, 3, 4, 5, 6, 7, 8],
    i, len;

for (i = 0, len = values.length; i < len; i++) {
    if (i == 2) {
        break; // 迭代不会继续
    }
    process(values[i]);
}

这里的循环体只会执行两次,然后在第三次执行 process()之前就终止循环了,尽管values数组中的元素超过了三个。

continue

第二种更改循环执行过程的方法是使用continue。continue语句可以立即退出(本次)循环,而进入下一次循环迭代

var values = [1, 2, 3, 4, 5, 6, 7, 8],
    i, len;

for (i = 0, len = values.length; i < len; i++) {
    if (i == 2) {
        continue; // 跳出本次迭代
    }
    process(values[i]);
} 

这里循环体将执行两次,跳过第三次迭代,而后进入第四次迭代,循环继续执行直到最后一次迭代(如果中途不再会打断的话)

Crockford的编程规范不允许使用continue。他主张代码中与其使用continue不如使用条件语句。比如说上一个语句修改为

var values = [1, 2, 3, 4, 5, 6, 7, 8],
    i, len;

for (i = 0, len = values.length; i < len; i++) {
    if (i != 2) {
        process(values[i]);
    } 
} 

作者推荐尽可能避免使用continue,但也没有理由完全禁止使用,它的使用应当根据代码可读性来决定

for-in循环

for-in循环是用遍历对象属性的。不用定义任何控制条件,循环将会有条不紊地遍历每个对象属性,并返回属性名而不是值。

for-in循环有一个问题。就是他不仅变量对象的实例属性,同样还遍历从原型链上继承来的属性。当遍历自定义对象的属性时,往往会因为意外结果而终止。处于这个原因,最好使用hasOwnProperty()方法来为for-in循环过滤出实例属性。

var prop;

for (prop in object) {
    if (object.hasOwnProperty(prop)) {
        console.log("property name is " + prop);
        console.log("property value is " + object[prop]);
    }
}

作者推荐使用hasOwnProperty()检测,如果是想遍历查找原型链上的值可以补充注释

var prop;

for (prop in object) {  // 包含对原性链的遍历
    console.log("property name is " + prop);
    console.log("property value is " + object[prop]); 
}

错误:使用for-in遍历数组

var values = [1, 2, 3, 4, 5, 6, 7, 8],
    i;

for (i in values) {
    process(values[i]);
} 

使用for-in遍历数组会造成潜在错误,记住,for-in循环是用来对实例对象和原型链中的键(key)做遍历的,而不是用来遍历包含数字索引的数组的。因此for-in循环不应当用于这种场景

原文:https://www.cnblogs.com/wangzhaoyv/p/14136174.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!