`
caolixiang
  • 浏览: 8020 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

雄辩的JavaScript第二章(经典翻译计划1)

    博客分类:
  • Js
阅读更多

 

第二章:JavaScript基础:值,变量和控制流

 

在电脑世界中,只有数据:除数据之外的东西是不存在的。虽然,本质上,所有数据都是由0-1比特位组成的序列,但是每一块数据都有自身的作用。在JavaScript中这些数据被整齐地区隔为值,每一个值的类型决定了它可以扮演的角色,JavaScript中有6种基本类型的值:数、字符串、布尔值、对象、函数和undefined

 

创建一个值,你只需要创建它的名字。非常方便是吧!你不用去找创建值的材料,没有一点成本,仅仅召唤一句:我要一个值!嗖的一声,你就拥有了一个值。当然,这些值不是从真空中产生的,每一个值必须存放在某处,如果你在一个时间点进行大数量级地调用,很快电脑的内存将会被耗尽。不过还好,这种问题只会在同步调用大量的数据时发生,一旦你不再使用一个值了,它将会被驱散掉,留下几个比特的尸体,这些尸体会在下一轮值的创建中被回收利用。

 

 

数字类型的值,像下面这样表示,估计你已经知道了。

 

114

 

JavaScript控制台中输入它,同样的数字会在输出窗口中显示出来。过程这样的:你所输入的字面量被转化为了一个数字类型的值,然后JavaScript控制台将这个数值写回屏幕。做点练习?意义似乎不大,很快我们将会学到不用这么直接的方式去创建数值,那个时候再去JavaScript控制台中试试吧。

 

114的比特串是这个样子的:

 

0100000001100010000000000000000000000000000000000000000000000000

 

一共64个比特位。JavaScript的数值总是占用这个长度,所以可表达的数的范围在JavaScript中是有限的。3个十进制的数位,仅仅可以表示0999,一共10^3个数。64个二进制数码,2^64个数,其实已经很多了,比10^9还要大(1的后面跟190)。

 

当然并不是小于10^19的数都可以表示,因为还有负数呢!必须牺牲一个比特位来保存符号。问题来了,不是所有范围的数都可以表示,除此之外我们还要占用另外11个比特,去储存十进制数码间的小数点。

 

这么看来只剩下52位了。所以表示的范围小于2^52,这个数量级比10^15要大,这个范围内的数值在JavaScript中是安全的。在许多情形中,涉及到的整数都在这个范围内,所以我们完全不用在意这些比特的细节。还不错吧,但是我们没有对付比特位特别有效的办法,许多时候你还是需要它们来帮助你完成你的工作的,它们对表示大数特别有效果。

 

分数用一个小数点分隔:

 

9.81

 

对于特别大或者小的数,可以使用科学计数法表示,加上e并且在e后面跟上指数。

 

2.998e8

 

这个数表示2.998 × 10^8 = 299800000

 

如果整数计算结果可以用52bit表示,那么准确性是可以确保的。不幸的是,分数通常不那么准确。像π这样的无理数,无法用分数精确表示。许多数还会失去准确性,除非64bit都来存放它们。好尴尬的啊,但是这个问题通常只会在特别的场景中才会给你带来麻烦。注意它,是给你的一个提醒——总是把分数看做是近似值,不要把它们看做精确值。

 

 

通常我们用这些数来完成计算。像“加”或者“乘”这样的计算符,以两个数值作为操作数,并且产生一个作为结果的数值。JavaScript中应该这样使用:

 

100 + 4 * 11

 

+”和“*”被称为操作符。第一个符号代表加法,第二个代表乘法。将操作符放在两个数值之间,将会在这两个数值上产生作用,产生一个新的数值。

 

上面这个值代表计算4100的和,然后在乘以100吗,还是代表先乘后加?你一定猜到了,首先做乘法。在计算之中,可以通过括号改变计算的顺序。

 

(100 + 4) * 11

 

减法使用“-”操作符,除法使用“/”操作符。如果操作符同时出现,并且没有括号,计算将按照优先级进行。第一个例子说明乘法的优先级比加法高。完整的优先级应该这样描述:先乘除,后加减。

 

试着计算一下这个值,然后在JavaScript控制台中键入这个表达式,看看结果

 

115 * 4 - 4 + 88 / 2

 

不要担心优先级的问题。心里如果没有底,加个括号吧。

 

有个操作符,或许你还不是很熟悉。“%”是取模操作符。X % Y X 除以 Y后得到的余数。例如 314 % 100 1410 % 3 1144 % 120。取模运算的优先级在乘法和减法之间。

 

 

下面一种值的类型是字符串。如果仅仅从从名称上推断用途,没有数值那么显而易见,但是它非常的基础和重要。字符串用以表示一个文本,字符串值得名称来源于一系列字符组成一个串的事实。用双引号包裹字面内容,就可以得到一个字符串:

 

"Patch my boat with chewing gum"

 

似乎一切都可以包裹在双引号之中,JavaScript会以一个字符串来对待它们。但是一些字符很恶心。你不妨想想把双引号放到双引号中的样子。

 

换行符,也就是当你敲击回车后的效果,也不能放到引号之间,字符串必须是一行。

 

为了将这些恶心的字符放到字符串之中,我们要使用一个小技巧:一旦引号中出现了“\”那么他后面的内容就会有特殊的含义了。“\”后面的引号不代表字符串的结束,它是字符串的一部分。“\n”,会被解释为一个换行符;“\t”会被解释为一个制表符。

 

"This is the first line\nAnd this is the second"

 

当然如果希望只看到“\”也有办法,双写“\”就可以了。

 

"A newline character is written like \"\\n\"."

 

 

字符串上没有除法、乘法和减法操作。不过可以使用“+”操作符,“+”并不是执行加的操作,而是连接操作,它将两个字符串连接在一起:

 

"con" + "cat" + "e" + "nate"

 

还有许多操纵字符串的方法,接下来会慢慢介绍。

 

操作符并不是都是符号,有些操作符是字母。例如,typeof这个操作符,它会返回一个字符串结果说明你需要查询的值的类型。

 

typeof 4.5

 

这之前看到的操作符都是操作两个值,但是typeof只有一个操作数。我们把需要两个操作数的操作符称为二元操作符,只需要一个操作数的操作符称为一元操作符。减号既可以作为一元操作符,也可以作为二元操作符:

 

-(10 - 2)

 

 

还有一种值称为布尔类型。值只有两种:truefalse。下面展示了一种产生布尔值的方法:

 

3 > 2

 

当然,通过下面的方式可以产生false:

 

3 < 2

 

>”和“<”你应该早已了解,它们是二元操作符,结果产生的布尔值表示两个操作数是否满足这种关系。

 

字符串也可以加以比较:

 

"Aardvark" < "Zoroaster"

 

上面的字符串是按照字典顺序加以比较的。通常大写字母比小写字母小,所以"Z" < "a"将产生布尔值true。非字母字符(!,@等等)仍然有一定顺序,它们的比较通常是基于Unicode标准的。这个标准把字符映射为整数,当然也包含了希腊、阿拉伯、日本、泰米尔这些语言的字母。这种映射可以方便地将字符储存在电脑之中——通过一系列数字,就可以表示这些字母。当比较字符串时,JavaScript仅仅只需要从左到右比较这些数字。

 

"Itchy" != "Scratchy"

 

 

 

布尔值间实用的操作符也不少。JavaScript支持三个逻辑操作符:与、或、非。它们可以用以布尔运算。

 

&&”操作符表示逻辑与。它是一个二元操作符,当且仅当两个操作数为真时,结果才为真。

 

true && false 

 

||”操作符表示逻辑或,两个操作数中一个为真,结果就为真。

 

逻辑非用“!”表示,它是一个一元操作数,总是对给定的值取反。!truefalse!falsetrue

 

 

Ex.2.1 

((4 >= 6) || ("grass" != "green")) &&

!(((12 * 2) == 144) && true)

 

结果为真吗?为了代码的可读性,最好还是添加必要的括号,这样写是不是简单多了?

 

(4 >= 6 || "grass" != "green") &&

!(12 * 2 == 144 && true)

 

的确,最终值为真。你可以化简最后合并计算:

 

(false || true) && !(false && true)

 

true && !false

 

true

 

你注意到"grass" != "green"为真了吗?草的确是绿色的,但是不等于绿色。

 

 

需要括号的场景并不是显而易见的,检查所有的操作符是一种方法。“||”的优先级最低,然后是“&&”,(> ==)这些比较操作符要再高一些,然后是其他的操作符,记住这些原则,一切从简,括号越少越好。

 

 

到目前为止的所有例子,似乎把JavaScript当成了一个口袋计算器。输入一些数值,使用操作符,然后产生新的值。创建值在JavaScript中是必不可少的一部分,但是仅仅是一个部分。产生值的过程也被称为表达式计算。每一个直接写出的值也是表达式(例如22 或者 psychoanalysis”),当然括号里的部分也是表达式,一个二元操作符可以作用在两个表达式上,一元操作符可以作用在一个表达式上。

 

创建表达式有多种方法,后面会慢慢道来。

 

比表达式更大的单元是语句,程序是由语句组成的。语句以最好以“;”结尾。最简单的语句是一个表达式跟着一个分号。

 

1;

!false;

 

当然这个语句没有实际意义。表达式可以产生一个值,而语句足以通过量变的积累来改变世界。它可以在屏幕产生输出,多数时候会影响之后的语句。这些变化被称作“副作用”。上面的语句仅仅是产生1true,然后立刻将其置入比特桶之中,什么以不留下,当然也不产生副作用。

 

 

程序如何记录内部的状态?它是怎么记住发生过的事情?我们已经知道如何通过旧值产生新值,但是这样不会改变旧值,新值要么被立即使用,要么随后消失。为了捕获值,javascript有了变量的概念。

 

var caught = 5 * 5;

 

一个变量总是有一个变量名,它指向一个值,用以保持这个值。上面的语句创建了变量名为caught的变量,然后通过它捕获了由5 * 5产生的值。

 

上面的程序执行后,你可以再控制台输入caught,你可以重新得到25这个值。变量名用以引用和获得它所保存的值。caught + 1 一样可以正确执行。变量名可以作为一个表达式,也可以作为更大表达式的一部分。

 

var关键词用以创建一个变量。在var之后是变量名。几乎可以用任何词命名变量名,但是其中不可以包含空格。数字可以作为变量名的一部分,catch22是一个有效的变量名,但是不能以数字作为变量名的起始。“$”和“_”可以像字母一样表示变量名,$_$也是一个有效的变量名。

 

如果你希望新的变量立刻捕获一个值,可以通过赋值“=”操作符实现。

 

当一个变量指向一个值时,并不意味着永久的指向。任何时候,都可以通过赋值操作让变量指向一个新值。

 

caught = 4 *4;

 

你可以把变量名想象成触手而不是盒子。它们不包含任何值,但是可以抓住值,两个变量可以指向同一个值。当然只有活动状态下的变量才可以访问它指向的值。

 

当你需要存储某些东西时,你制造一个触角并持有它,或者用原有的触角指向新的值:为了记录Luigi欠你钱的金额,你可以这样做:

 

var luigiDebt = 140;

 

然后,每一次Luigi还你钱时,总是可以通过让变量指向一个新的的数值,来减少他欠你钱的总量:

 

luigiDebt = luigiDebt - 35;

 

某一个时刻,变量、值的集合被称为环境。只要程序开始执行,环境就不会为空。环境中总是包含了许多标准变量。当你的浏览器载入一个页面时,它会创建一个环境,并在环境中附属这些标准变量,直到载入新的页面,都可以创建和修改这些变量。

 

……

 

环境中许多标准变量都是函数类型的。函数就是把一系列代码包装到一个值中。这一系列代码可能非常有用,通过包含它们的函数名就可以调用这些代码。在浏览器中,alert变量持有一个现实包含了信息的对话框窗口的函数,可以这样使用:

 

alert("Also, your hair is on fire.");

 

执行函数中代码的过程被称作调用,调用的标志是使用括号。每一个产生函数值的表达式都可以在其后加上括号表示对它的调用。括号中的字符串值被传递到函数中,这个值就是要在对话框窗口中显示的文本。传递给函数的值被称作参数。alert只需要一个参数,其他函数可能需要更多。

 

……

 

显示对话框有一些“副作用”。一些函数之所以有用是因为它们产生了“副作用”。当然函数也会产生一个值,这样的情况之下不需要产生“副作用”。例如,Math.max这个函数,它接收两个参数,并且返回其中较大的一个:

 

alert(Math.max(2,4));

 

当一个函数产生一个值时,这个过程被称作返回“return”。因为产生值的函数总是JavaScript表达式,因此函数调用可以成为更大的表达式的一部分:

 

alert(Math.min(2,4) + 100);

 

第三章将讨论如何自定义函数。

 

……

 

如同上述的例子展示的那样,alert对于显示一些表达式的结果很有用。但是不停让用户点击这些对话框会让他们崩溃,从现在开始,我们探讨一些另外的机制,使用一个类似的函数——“print”。“print”不会弹出窗口,仅仅只是把值在JavaScript控制台中输出。“print”不是标准的JavaScript函数,浏览器不会把它提供给你,但是在这本书中,这样做是可行的,在下面这些页面中你可以这样使用:

 

print("N");

 

show也是一个相似的函数。print将以文本的形式显示参数,而show将会尽力显示参数在程序中的样子,传递更多关于值的类型的信息。当把文本传递给show时会一并带上引号:

 

show("N");

 

标准环境中提供了弹出窗口的其他一些方法。可以通过confirm函数询问用户可否。函数会返回一个布尔值,如果用户点击了是将返回true,反之,返回false

 

show(confirm("Shall we, then?"));

 

prompt用于询问开放式问题,第一个参数是询问的问题,第二个参数是用户键入文本前的默认字符。用户可以在窗口中键入一行字符串,函数最终会以一个字符串的形式返回它们。

 

show(prompt("Tell us everything you know.","..."));

 

……

 

赋予环境中每一个变量新的值是可行的。可能会很有用,但是很危险。当你把8传递给print后,它便再也不能工作了。幸运的是,通过JavaScript控制台上大大的重置按钮,你可以将环境恢复至初始状态。

 

……

 

每个程序如果只有仅仅一行代码,将会特别无趣。当你将多行语句放入一个程序中时,它们会以此从上到下的执行。

 

var theNumber = Numer(prompt("Pick a number",""));

print("Your number is the square root of " + theNumber * theNumber);

 

Number函数将一个值转化为一个数值,这所以这样使用是因为,prompt返回的是一个字符串 StringBoolean这两个函数也很相似,它们会把值转化成对应的类型。

 

……

 

下面考虑一个实际的问题,输出012的所有偶数。下面给出一种方法:

 

print(0);

print(2);

print(4);

print(6);

print(8);

print(10);

print(12);

 

可以达到目的,但是编程的精义是简化工作。如果目标变为输出1000一下的所有偶数,这个方法就不那么凑效了。我们需要的是一种自动地执行一系列代码段的方法。

 

var currentNumber = 0;

while (currentNumber <= 12) {

print(currentNumber);

currentNumber = currentNumber + 2;

}

 

在第一章中,你已经看到过while方法了。以while开始的语句完成循环的操作。循环放在一系列语句之中,它会使得程序代码被执行多次。在上面的代码中,while包含了括号中的表达式(当然表达式是必须的),用于控制循环的结束。当表达式产生的布尔值为true时,代码会被重复执行。一旦布尔值变为false,程序会跳出循环。

 

变量currentNumber的设置展示了一种通过一个变量跟踪程序进程的方法。每一次循环重复,这个变量会加2,每一次循环,在头部,都会和12做一个比较以此决定是否继续循环。

 

while语句的第三部分是另外一个表达式。是循环体,也就是需要多次执行的动作,如果我们不需要输出数,程序可以这样写:

 

var currentNumber = 0;

while (currentNumber <= 12)

currentNumber = currentNumber + 2;

 

在这里currentNumber = currentNumber + 2;这个表达式构成了循环体。如果输出这些数是必须的,那么循环体得包含多个语句。{ }用于构建代码块。从大括号外面看,代码块就如同一个语句。在上面的例子中,代码除了打印数值还完成更新currentNumber的工作。

 

 

练习2.2:通过上面介绍的方法,计算并输出2^10。不允许通过2*2*2...这样的方法。

 

如果觉得有困难,看以参照序号为偶数的例子。程序必须完成规定量的操作,while循环中的计数器用以确保操作的完成,程序用某个结果乘以2而不是输出计数器的值,某个结果也是一个变量,结果通过这个变量来产生。

 

如果你还未弄清楚细节,不要着急。即使你完全理解了这章中所有的技术,也不代表你可以顺利地解决这一章中出现的问题。阅读和编写代码可以培养解决问题的感觉,多研究解决方法,并且在下一个例子中联系一下。

 

var result = 1;

var counter = 0;

while (counter < 10) {

result = result * 2;

counter = counter + 1;

}

show(result);

 

计数器从1开始,并且通过小于等于10来作为判断。这样理解很容易,当然当你习惯了从0开始,将会是一个不错的选择。

 

显然,你的解决方法可能和我的不尽相同,能够解决问题就行,如果它们显得很难,那么理解我的解决方法是必须的。

 

 

练习2.3:通过一些微小的改动,上面例子中的程序就可以用来画三角形了。“三角形”是一些文本,只是你看上去觉得像三角形。

 

输出10行,第一行有一个“#”,第二行两个“#”,并以此类推。

 

如何让一个字符串中有X个“#”呢?一种解决方法是建立一个内循环——循环中的循环。一种更简洁的方式是利用上一次循环中产生的字符串,然后在其尾部加上一个字符。

 

var line = "";

var counter = 0;

while (counter < 10) {

line = line + "#";

print(line);

counter = counter + 1;

}

 

 

 

可能你已经注意到一些语句前的缩进了,缩进不是必须的:没有缩进计算机仍然可以很好地接受它们。实际上,换行也不是必须的。你可以随性把程序写成长长的一行。缩进的作用是使得代码的结构明晰、易读。程序块中会包含其他程序块,这样你会分不清是程序块开始还是结束,增加了缩进后,程序中的逻辑块会形成与之相一致的视觉单元。我喜欢用两个空格表示缩进,当然因人而异。

分享到:
评论
1 楼 wizardforcel 2017-10-27  
所以后面就没了吗。。。

相关推荐

    Eloquent-[removed]JavaScript | 雄辩JavaScript第二版

    学习JavaScript雄辩JavaScript,第二版引言完毕(第1部分:语言) 值,类型和运算符| 完毕计划结构| 完毕功能| 完毕数据结构:对象和数组| 完毕高阶函数物品的秘密生活项目:电子生活错误和错误处理常用表达模组项目...

    雄辩的JavaScript,第一版-精打细算的编程指南Eloquent JavaScript, First Edition - An Opinionated Guide to Programming

    提供了针对初学者的JavaScript编程语言的全面介绍。 包含大量示例程序和环境以供试用和使用。

    雄辩的JavaScript书的来源.zip

    《雄辩的JavaScript》是一本深受开发者喜爱的JavaScript编程书籍,其开源版本被广泛传播和学习。这本书深入浅出地讲解了JavaScript的核心概念和技术,帮助读者掌握这门强大的脚本语言。JavaScript,作为互联网上最...

    eloquent-[removed]雄辩JavaScript,第3版

    雄辩JavaScript-第三版(2018)内容索引阶段1:说明第2阶段:nex步骤架构图定义和首字母缩略词注意:这些术语中的许多都需要有关AWS服务和产品的知识,有关更多信息,请参阅 AQI:空气质量指数AWS:Amazon Web服务...

    eloquent-javascript-solutions:雄辩JavaScript书中的解决方案

    《雄辩JavaScript》是一本广泛受到开发者欢迎的开源书籍,主要涵盖了JavaScript编程的各种核心概念和技术。这本书通过深入浅出的方式,引导读者理解并掌握这门强大的脚本语言。"eloquent-javascript-solutions"这个...

    eloquente-[removed]《 Eloquent JavaScript》第二版的翻译

    雄辩JavaScript-第2版对JavaScript,编程和数字奇迹的现代介绍。书籍内容-(第1部分:语言)-(第2部分:浏览器) 文档对象模型处理事件项目:游戏平台在画布上绘图HTTP 表格和表格栏位项目:绘画程序Node.js- (第3...

    eloquent-js-samples:雄辩JavaScript示例

    《雄辩JavaScript示例》是基于JavaScript编程语言的一份学习资源,主要针对Eloquent JavaScript这本书中的实例代码。这本书深入浅出地介绍了JavaScript的核心概念和技术,是很多开发者学习JavaScript的首选教材。...

    EJS:雄辩的Javascript

    《EJS:雄辩的JavaScript》是一本深入探讨JavaScript编程的权威著作,也被称为《Eloquent JavaScript》。这本书以其清晰的阐述和丰富的实践示例,为读者提供了全面了解JavaScript语言和Web开发的宝贵资源。在...

    雄辩的javascript练习

    第02章 第03章 第04章 :thinking_face: 运行脚本 您如何通过终端运行JavaScript脚本? 只有安装了NodeJs运行时,才可以从终端运行JavaScript文件。 如果已安装,则只需打开终端并输入 node FileName.js 脚步 : ...

    egg_language:雄辩的javascript项目2

    在“egg_language:雄辩的javascript项目2”中,我们主要关注的是JavaScript编程语言的应用与实践。这个项目可能是一个教学资源或一个实际的项目案例,旨在帮助开发者通过实践提升JavaScript技能。JavaScript是一种...

    eloquent-javascript-solutions:Marijn Haverbeke在第三版雄辩的javascript中设置的练习和问题的个人解决方案

    《雄辩的JavaScript》是 Marijn Haverbeke 所著的一本开源编程书籍,它深入浅出地介绍了JavaScript这门强大的编程语言。书中的练习和问题旨在帮助读者加深理解,提升实践能力。这里提到的"eloquent-javascript-...

    WDB:我的笔记和实践练习来自Colt Steele的2021 Web开发人员Bootcamp +雄辩JavaScript

    WDB:我的笔记和实践练习来自Colt Steele的2021 Web开发人员Bootcamp +雄辩JavaScript

    elomach:使用threejs和雄辩的javascript模型

    在这个名为"elomach:使用threejs和雄辩的javascript模型"的主题中,我们将深入探讨如何使用Three.js结合JavaScript来构建3D模型,并了解相关知识点。 首先,让我们了解一下Three.js的核心概念。Three.js提供了一个...

    eloquent-3:举行JavaScript雄辩的第三版练习

    `Eloquent JavaScript 3` 是一本专注于JavaScript编程的权威书籍的第三版,旨在帮助开发者深入理解这门语言,并提升编程技巧。这本书通过一系列的练习,让读者在实践中掌握JavaScript的核心概念和高级特性。 **一、...

    eloquent-[removed]雄辩的javascript练习解决方案

    《雄辩的JavaScript》是一本深受开发者喜爱的在线书籍,主要涵盖了JavaScript的基础知识以及高级特性。这本书通过一系列的练习和项目,帮助读者深入理解和掌握这门语言。在解压缩后的文件"eloquent-javascript-...

    eloquent-[removed]口才JavaScript练习

    第二章:程序结构 循环三角形 嘶嘶声 棋盘 第三章:功能 最低限度 甚至 豆计数 第4章:数据结构-对象和数组 范围的总和 反转数组 一个列表 深度比较 第5章:高阶函数 展平 母子年龄差异 历史预期寿命 每隔一段时间 ...

    Eloquent-[removed]Eloquent JavaScript第二版练习

    Eloquent JavaScript第二版练习 我是一个初学者,很高兴能入门。 我一直在阅读Eloquent JavaScript,并在Udemy上了几节课。 此回购是我通过Eloquent JavaScript书进行工作时完成的练习的集合。

    昆体良雄辩术原理PPT课件.pptx

    昆体良提出了四个阶段的教育计划:家庭教育、初级学校学习内容、文法学校学科和雄辩术学校学科。 在家庭教育阶段,昆体良强调了早期教育的重要性,提出了双语教育(bilingual education)的概念,认为儿童应该从小...

    雄辩

    "雄辩"通常指的是在JavaScript编程领域中,一种优雅、清晰且有说服力的编码风格或表达方式。这种风格能够使代码更具可读性,更易于理解和维护,从而提升团队合作效率。JavaScript作为Web开发的核心语言,其语法灵活...

Global site tag (gtag.js) - Google Analytics