对很多人来说,学写代码很难。本文将通过编写与众不同且富有诗意的代码来克服学习代码最初遇到的困难。如果你是个JavaScript新手,或者是在编程学习过程中遇到了困难,本文介绍的方法也许可以帮到你。
为什么学习编程这么难?
以下是人们对编程很难学及JavaScript(或任何编程语言)很枯燥的一些误解:
- 代码晦涩难懂令人望而生畏,只有实用功能毫无乐趣;
- 代码仅适用于机器,人们无法与它交流或参与其中;
- 代码不算一种语言,因为它与一般语言的用法截然不同,形式上的差别也很大;
- 提到程序员,人们就会想到邪恶的黑客或黑客帝国的成员等刻板形象,因此没有认同感。
未接触编程的人
开发人员需要以一种非常特殊的方式看待代码,甚至要以一种完全不同且高度逻辑化的方式来思考。编程语言非常严格,对错误零容忍,单个字符就可能使机器无法理解人们的意思,并使应用程序奔溃。学习编程时,应将之前学习人类语言时的读写规则归零(顺便说一下,在学习一种新的人类语言时也是如此)。
但并非网上的编程语言、文档或视频教程都是针对“从人类语言到编程语言的转换”这一思维而编写的。当然,他们也没有必要这样做。毕竟,写代码的主要是为了告诉机器要做什么。
鉴于此目的,没有机会对这两种语言进行比较,因此人类的语言(包括词汇和语法规则)似乎对学习编程语言毫无用处。JavaScript语言中没有“爱”这个词,“我爱你。”这句话在其中也没有意义。机器(或浏览器)根本不理解爱。这种“闻所未闻”、“无从下手”的感觉可能会让人感到害怕。
***次接触编程的人
这就是本文的意义所在,借助已掌握的人类语言知识,将JavaScript看作一种人类语言,以一种更容易、更具艺术性的方式来学习它。举个小例子来说明吧!
一个有趣的事实是,一些编程语言实际上已经从一种编程语言转换到另一种编程语言。这就是为什么掌握多种编程语言变得简单多了——只学一门编程语言就够啦。
一个小例子
例如,在很多情况下,要想运行JavaScript代码,需要准备好“文档”(基本上是网站,用户每次访问时都在下载),以便与HTML元素进行交互。在纯JavaScript语言中,可能会偶然发现以下内容。
- (function() {
- // Your code goes here
- })();
或者有时像这样:
- if (document.readyState === ‘complete’) {
- // Your code goes here
- }
上述***个代码肯定需要加以解释,而对第二个代码(也许需要一些想象),可以这样理解:满足了必需的某个条件后,后续步骤仅通过观察就能进行下去。
试想这样的场景:
- onceUponATime(function () {
- // Your code (story) goes here
- })
连小孩都能理解“Once upon a time” (“曾几何时”)这样的内容。这种内容在与开发者对话(通过唤起他们的童年回忆),同时在理论上也能做开发。这就是“让人类语言转换为编码语言”的想法。
关于“functions(函数)”的简要说明:函数基本来说是一种技能,在调用之前处于休眠状态。“To read”是function read() { …}}的一项技能,想读取某内容时就写成这样:read(),就会调用才会调用该函数。还有一种是“匿名函数”,即function(){ … }(没有名字,就像上面的代码片段那样),它基本上是“一次性的临时操作”,甚至不算一种技能,例如“按下按钮”。
扭转乾坤:从信息到基础
要更进一步了解这个想法,可将上述的原因和误解颠倒过来:
一首小诗,
用JavaScript语言编写。
为人类而写,
讲述两个人之间的爱。
- // Love at first sight
- if (me.getDistanceTo(you.position) < 200) {
- me.setFeelings({
- inLove: true,
- });
- }
它不具有功能性,目前也不适用于机器,只是方便人们阅读和理解。
如果你能看懂这首诗,你实际上是理解了一段JavaScript代码,也许你还会拿来与英语进行比较。
现在你可能会问自己:我理解这一点,但它为什么这么写呢?这种语言背后的规则(语法)是什么呢?“me”在技术层面是什么意思?为什么这段代码看起来很像英语?
规则、词汇和变量
学习编程语言时,最重要的事情之一就是理解变量的概念。
每一种人类语言都有其规则(语法)和大量词汇(意思均已知)。显然,只有先学习这两点才会说这种语言。
与许多其它编程语言一样,JavaScript也有一套规则(例如,单词之间要加“.”或如何编写“if”语句)和词汇(if、document、window、Event等)。这些关键字由JavaScript(和浏览器)所有(或“预先定义”),并且每个关键字都有其特定用途。
就像之前提到的那样,似乎没有机会去和英语中的单词和句子做比较,因为JavaScript中根本没有对应的词和句子。
这就是引入变量这个概念的原因,开发人员可以(甚至必须)定义变量,以便让机器和开发人员理解某些东西代表什么。变量可以采用多种形式(因此得名):它们可以是一串单词和字母(字符串)、数字、操作(函数)、甚至集合(数组),不胜枚举。
在所有人类语言中,可能都有一个关于“love”的词,你大概明白它是什么意思,但不太肯定,因为它太主观了。但无论怎样,还是有一个词可以形容它。
但在JavaScript中,如果不定义“love”,就没有与之对应的表达,至于形式,则完全取决于你。
- var love = {
- color: ‘red’,
- duration: 365,
- loveTarget: ‘cats’,
- };
- // a simple variable expression,
- // where love is an object “{ … }”, a thing
- // with some properties (color, duration, loveTarget).
- const love2 = {
- color: ‘purple’,
- duration: ‘forever’,
- loveTarget: ‘dogs’,
- };
- // also a variable expression, where love2 (aconstant),
- // cannot be redefined / overwritten completely:
- // love2 = undefined; // => will not work
- // (“undefined” is a pre-defined javascriptkeyword,
- // basically saying “has no value”)
区分JavaScript中预定义的内容(JavaScript规则和词汇表)与开发人员实际自定义的内容(也称为“应用程序逻辑”或“业务逻辑”)十分重要。
回到上面写的诗:
- // Love at first sight
- if (me.getDistanceTo(you.position) < 200) {
- me.setFeelings({
- inLove: true,
- });
- }
这些表达式来自以下JavaScript词汇表规则集:
- if (…) { … }
- // if statement: when … is met, do things in { … }
- {
- inLove: true,
- }
- // an “object” with some info, some thing in the world.
- // can contain other info, and “skills” (functions).
- // “inLove” is a custom property,
- // “true” is pre-defined in javascript, (meaning: “yes”)
- // and the value of “inLove”.
- .
- // needed to access an objects property “my name: me.name”
- getDistanceTo()
- // an expression to “call” a function (a “skill”).
- // getDistanceTo is custom (not JavaScript), and a function,
- // so it can be executed / called upon with the “()” after.
- // sometimes you can pass arguments in those brackets (like “position”)
- // to change the outcome of a function.
这些是变量,可以自定义它们的名称和行为。
- me // an object, some thing in the world
- you // an object, some thing in the world
- position // an info about “you”, accessed by the “.”
- getDistanceTo // a skill of me, accessed by the “.”
- getDistanceTo() // the skill, with javascript grammar telling: do it.
- getDistanceTo(position) // same, but do it with “position”.
- setFeelings // another skill of me, accessed by the “.”
- setFeelings({ inLove: true }); // the skill, with some instructions (anobject).
假设这是一首人类读得懂的诗,你可能已经理解了其中的信息,也可能看到了需要遵循的JavaScript语言规则与需要提出的内容(变量)之间有何区别。
但机器又会怎么做呢?
如果是机器(浏览器)读取这首诗,那就会识别为错误。机器需要一个“me”和“you”的定义,因为它试图访问其属性(通过在me.getDistanceTo()中的“.”来访问)。有了上面提到的区分能力,实际上你可以设计“me”和“you”,让计算机能够执行或读取诗,如下所示:
- // This is how the definition of a being (me/you)could look like
- var me = {
- position: {x: 0, y: 0} // some coordinates, maybe
- getDistanceTo: function(position) {
- // calculate the distance, relative to own position
- },
- setFeelings: function(feelings) {
- // handle those feelings…
- }
- }
- var you = {
- position: {x: 0, y: 0} // some coordinates, maybe
- }
- // the poem itself
- if (me.getDistanceTo(you.position) < 200) {
- me.setFeelings({
- inLove: true,
- });
- }
那么在这里发生了什么?
- 为了让人们理解,读取一首用JavaScript“语法”编写而成的JavaScript诗;
- 在理解信息之后,为理解诗的结构(JavaScript的语法和基础知识),对规则、词汇和变量进行了区分;
- 通过这种区分后,使用JavaScript规则设计了其余的诗歌变量,使其可以通过机器(在浏览器中)运行。
这可以做到,因为处理JavaScript,就像处理英语语言一样。
更大的例子:交互式代码诗歌
LoveBits是一种代码学习或用代码讲故事的体验。
LoveBits:基于JavaScript的代码诗歌项目
它试图通过以下方式让人们对JavaScript或代码感兴趣:
- 将可读性和人类语言放在***位;
- 将代码与读者可能熟知的艺术形式相结合。
故事情节与两个比特(矩形状)有关;其中一个比特(blueBit)是浪漫主义者,为另一个比特(purpleBit)写出JavaScript的爱情诗。
启动LoveBits时,可选择其中一首爱情诗(由JavaScript代码编写而成)。每首诗都有一个代码片段,不甚熟悉编程的人都能理解其中的编写方式。这个项目唯一的要求就是要懂英语。
例如,“love at first sight”(实际上是LoveBits诗歌中的一首)讲述的是这两个比特之间的故事,诗中,blueBit大致是这么说的,“If I get close enough toyour position, I will ‘set my feelings’ to inLove: true.”
这些诗歌的特殊之处在于你可以通过点击下面的“play”按钮,“run”或“play”它们。在“Love at first sight”的诗中,你会见到一个蓝色和紫色的矩形以及一个数字。正如你猜到的那样,它们就是诗中提到的两个比特,而blueBit下面的数字实际上是blueBit和purpleBit之间的距离。
正如诗歌所暗示的那样,你可能想要通过减少它们之间的距离让blueBit爱上purpleBit。那要怎么做呢?可以和blueBit互动,把它拖来拖去,让它坠入爱河。但要小心,有时结果可不只一种。
实际上有人可能会说程序员成为了这里的机器,但程序员才是需要解释JavaScript代码,并采取行动帮助两个数字生物坠入爱河的那个人。
未来将何去何从?
如果你是个奋力拼搏的开发者,试着将JavaScript视为人类语言吧,只了解需首先执行的代码片段就够了,不必去考虑它们最终运行的结果。
进一步的建议:
- 永远优先选择能将规则、词汇和变量组合在一起形成应用程序逻辑的整个应用程序;
- 应用程序逻辑会讲故事,这些故事将帮你填补上述代码示例中的空白。代码库和实用程序(如lodash)只能提供新的词汇表,在你能阅读和理解JavaScript代码后会有所帮助;
- 检查现有代码,并尝试将其分解为具有反映其功能名称的小函数。编写适用于人和机器的代码,编写出可以像句子一样阅读的代码,并在需要的地方加以注释。思考:怎么用人类语言(向另一个开发者)表述这个代码?
结论
将代码视为人类语言而不是外星人发明的东西,学习代码就会更容易。学习区分语言属性(内置)和应用程序逻辑的变量/自定义代码至关重要。理解了应用程序逻辑,你就无需了解语言特征即可作出改进和更改。
学习基础知识前需明白:理解了任一代码片段的信息,JavaScript的基础知识自然就能随之掌握。有多少次你听到有人说:“我能看懂这种语言,但我还不会说。”这是一个自然过程,能够并可能适用于人类语言和编码语言的学习。
此外,请牢记代码有明确的功能性目的,但也并非总是如此。即使是人类语言,曾经也只满足纯粹的功能性需求,后来才出现了诗歌甚至歌曲(说到这,有人对JavaScript歌曲感兴趣吗?)这些以截然不同方式使人们密切相联的语言形式。这同样适用于编程语言。