ホームページ > 記事 > ウェブフロントエンド > CoffeeScrip を使用して JavaScript コードを美しく記述する_JavaScript のヒント
JavaScript は間違いなく、Web 上で最も偉大な発明の 1 つです。Web ページ上のほとんどすべての動的効果は、JavaScript の豊富なコンピューティング能力に基づいています。そしてその機能は、Google Chrome で使用される V8 エンジンなど、さまざまな新しい JavaScript エンジンの下でますます強力になっています。
しかし、誕生が早すぎたため、現在では多くの文法定義がやや非効率になっており、歴史的な理由により、より高度な文法形式を現在の JavaScript 言語に追加することができません。これは残念なことです。
世界中の多くの天才が、より良い JavaScript を構築するために懸命に取り組んでいます。多くの試みが行われてきましたが、その中で最も有望なものは CoffeeScript と TypeScript です。 CoffeeScript に直面すると、一目で古い友人のように感じました。また、TypeScript にも非常に興味をそそられました。 CoffeeScript は TypeScript と同様、JavaScript にコンパイルされた言語であり、どちらも JavaScript の表現力を強化します。この記事は CoffeeScript についてです。TypeScript については次の記事で説明します。
いわゆる JavaScript へのコンパイルとは、CoffeeScript と TypeScript が独自のランタイムを実装せず、同等の JavaScript コードにコンパイルされ、JavaScript インタープリターで実行されることを意味します。
コーヒースクリプト
シンプルさ
CoffeeScript の最大の印象は、その簡潔な表現です。次のコードは、CoffeeScript 中国語からの抜粋です:
# 赋值: number = 42 opposite = true # 条件: number = -42 if opposite # 函数: square = (x) -> x * x # 数组: list = [1, 2, 3, 4, 5] # 对象: math = root: Math.sqrt square: square cube: (x) -> x * square x # Splats: race = (winner, runners...) -> print winner, runners # 存在性: alert "I knew it!" if elvis? # 数组 推导(comprehensions): cubes = (math.cube num for num in list)
上記のコードは、同等の JavaScript コードにコンパイルされます:
var cubes, list, math, num, number, opposite, race, square, __slice = [].slice; number = 42; opposite = true; if (opposite) { number = -42; } square = function(x) { return x * x; }; list = [1, 2, 3, 4, 5]; math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); } }; race = function() { var runners, winner; winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return print(winner, runners); }; if (typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!"); } cubes = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = list.length; _i < _len; _i++) { num = list[_i]; _results.push(math.cube(num)); } return _results; })(); run: cubes
CoffeeScript はシンプルさを追求しています。そのシンプルさは、まず、構文制御のみに使用されるいくつかのシンボルの削除に反映されます。これらには次のものが含まれます:
セミコロンをキャンセル
var 宣言をキャンセル
内部コードを囲む中括弧をキャンセルし、代わりにインデントを使用します
曖昧さがない場合、関数呼び出しでは括弧を省略できます
var 宣言には、複雑で役に立たない JavaScript 変数スコープ メカニズムが含まれています。この部分については今は話さないでおこう。 CoffeeScript は、var 宣言メカニズムを完全に排除することで問題を単純化します。つまり、CoffeeScript の世界では、変数を事前に宣言する必要はなく、変数を直接使用するだけです。そして、この使用法には基本的に危険はありません。
CoffeeScript のインデントは、コードを美しくするために使用されるだけでなく、特別な意味を持つコード レベルの構成も表します。簡単に言えば、内部コードを中括弧で囲むのではなく、内部コードをインデントする必要があります。異なるインデントは異なるコード レベルを表します。形式と内容が一致している。
インデントの例:
#if缩进 if true 'true' else 'false' #while缩进 while true 'true' #函数缩进 (n) -> n * n #对象字面量缩进 kids = brother: name: "Max" age: 11 sister: name: "Ida" age: 9
CoffeeScript 関数呼び出しでは、あいまいさを生じることなく括弧を省略できます。たとえば、console.log(object) は console.log オブジェクトに簡略化できます。いわゆるあいまいさの例としては、パラメーターがない場合、console.log が機能属性ログを取り出すのか、関数ログを呼び出すのかがわからないことが挙げられます。
CoffeeScript の関数式も非常に合理化され、合理化されました。 1 行の関数定義は次のようになります:
square = (x) -> x * x
複数行の関数もインデントによって整理されます。 -> のような空の関数が最も簡潔です。
この簡潔な関数式により、コールバック関数を渡すことが非常に便利になります。次のような配列のマップで十分かもしれません:
list = [1, 2, 3] list.map (e) -> e+1
同等の JavaScript コードがそれほどずさんであるはずはありません:
list = [1, 2, 3]; list.map(function(e) { return e + 1; });
拡張された表現
CoffeeScript は、JavaScript にはない強力な式構文を提供します。これは、構文シュガーとも呼ばれます。私の考えでは、そのような拡張機能はたくさんあります。代表的な例を 2 つ挙げます。
文字列補間
リスト解析
文字列補間メソッドは既存の文字列機能を拡張し、文法的に簡略化したものですが、リスト解析には概念の変更が含まれます。前者は改善であり、後者は変更です。
文字列補間
CoffeeScript 文字列では、#{…} を使用して式を埋め込むことができます。例:
「#{ 22 / 7 } は π の適切な近似です」
は以下と同等です:
"" (22 / 7) " は π" の適切な近似です;
ここでは補間がプレースホルダーの役割を果たし、動的コンテンツの文字列を簡単に構築できるようにします。この表現は誰でも受け入れられると思います。
リスト解析
リスト内包表記は、CoffeeScript の世界において重要な役割を果たします。それはサイクルについての考え方を変えます。 CoffeeScript は JavaScript のような for ループ構造を提供せず、すべてリスト分析に変換されます。次のような通常の JavaScript for ループ:
food_list = ['toast', 'cheese', 'wine']; for (i = 0, len = food_list.length; i < len; i++) { food = food_list[i]; eat(food); }
用CoffeeScript实现就是:
food_list = ['toast', 'cheese', 'wine']
eat food for food in food_list #做个小补充,for循环的单条语句的写法
单单是上面的例子不足以显示列表解析的强大(却看到它的简洁了)。在继续这个话题之前,我觉得我有必要补充一下另一个涉及到CoffeeScript理念的东西了:一切皆是表达式。
在CoffeeScript世界里,一切语句都是表达式语句,都会返回一个值。函数调用默认会返回最后一条语句的值。if条件结构也会返回值,其返回的是执行的最后一条语句的值。循环结构有些不同,其会将每次循环的结果都保存在一个数组里,作为此循环结构的值。例如下面代码的list结果就是[5, 4, 3, 2, 1]。
num = 6 list = while num -= 1 num
回到列表解析的主题。与while一样,for结构也是一种循环的表达,其结果也是一个数组。回到先前的例子,下面的小代码的list结果就是['t', 'c', 'w']。
food_list = ['toast', 'cheese', 'wine'] list = (food[0] for food in food_list)
我们已经看到for循环的each形式
eat food for food in food_list
以及它的map形式
(food[0] for food in food_list)
下面给出它的filter形式
(food for food in food_list when food is 'wine')
列表解析的特色的地方在于它改变了我们组织循环的方式和解析数组的模式。这是一种声明式的编程方法,告诉程序你想要什么而不去关心构建的过程。
类的支持
类是CoffeeScript对JavaScript的一个很重要的补充。JavaScript的原型功能很强大,写法上又恨别扭。正确地设置原型链以实现继承关系也是个很大的挑战。CoffeeScript从语法上直接支持类的定义,自然且隐藏细节。
class Animal constructor: (@name) -> move: (meters) -> alert @name + " moved #{meters}m." class Snake extends Animal move: -> alert "Slithering..." super 5 class Horse extends Animal move: -> alert "Galloping..." super 45 sam = new Snake "Sammy the Python" tom = new Horse "Tommy the Palomino" sam.move() tom.move()
从实现上来说,CoffeeScript的类与JavaScript的构造函数和原型链那一套并无二致。所以,理解原型机制也是理解CoffeeScript类的基础。
关于JavaScript的糟粕
CoffeeScript的另一个目标是从语法层面上直接消除JavaScript的被人诟病的一些糟粕部分。前面已经说过关于分号的部分。关于var声明的部分。分号的机制暂且不去例会,总之CoffeeScript不用再去写分号了。
在JavaScript当中,最为人诟病的糟粕部分有两处,因为它们使用的情况最多而且容易出错。
全局变量
相等比较
全局变量
JavaScript的作用域规则很复杂,涉及到var声明机制和变量提升。在JavaScript里,构造一个全局变量是很容易的,有三种方式:
在全局的环境里用var声明
var name = 'name';
在函数内用省略var的方式定义
function foo() { name = 'name'; }
창에 바인딩된 속성
window.name = '이름';
첫 번째와 두 번째 방법은 가장 흔히 잘못된 사용법입니다. 우선, 전역 환경에서 직접 코딩하는 것은 권장되지 않습니다. 대신 프로그램의 범위를 이 익명 함수로 제한하기 위해 익명 함수로 래핑해야 합니다. 두 번째 사용법은 var 선언을 완전히 잊어버리는 것입니다. 실제 JavaScript 코딩에서는 var 선언을 잊어버리는 경우가 많습니다(줄 끝에 세미콜론을 추가하는 것을 자주 잊어버리는 것처럼).
커피스크립트에서는 그런 걱정이 전혀 없습니다. 우선, 컴파일된 JavaScript 코드는 전역 환경에 노출되지 않습니다. 모든 코드는 자동으로 익명 함수(function(){ ... })();로 래핑됩니다. 그러면 모든 변수가 var로 자동 선언됩니다. 이렇게 하면 창에 할당을 사용하지 않는 한 실수로 전역 상황을 오염시키는 것이 어렵습니다.
동등성 비교
우리 모두는 JavaScript에 ==와 ===라는 두 가지 비교 연산자가 있다는 것을 알고 있습니다. 또한 ==는 사용하기 까다로울 수 있으므로 일반적으로 문자를 하나 더 입력하고 ===를 사용하는 것을 선호합니다. CoffeeScript에는 비교 연산자 ==가 하나만 있으며 JavaScript의 ===로 컴파일되므로 이러한 함정을 피할 수 있습니다.
커피스크립트를 쓸까
CoffeeScript는 JavaScript의 표현 능력을 단순화하고 향상시키며, 문법적인 측면에서 JavaScript의 일부 함정을 최대한 피합니다. 이를 사용하여 코드를 작성하면 사람들이 더 명확하고 편안해지며 실수하기가 덜 쉬워집니다. CoffeeScript의 원래 의도는 더 나은 JavaScript를 제공하는 것입니다.
그러나 CoffeeScript는 JavaScript와 호환되지 않습니다. JavaScript의 하위 집합도 상위 집합도 아니지만, JavaScript와는 분명히 다른 개념을 가진 언어입니다. CoffeeScript를 사용한 프로그래밍에는 개념의 변화가 필요합니다. 이 개념이 더 좋고 자연스럽더라도 자신의 방식에 얽매이는 일부 사람들이 단념하는 주된 이유입니다.
CoffeeScript는 모든 사람에게 적합하지 않습니다. 어떤 사람들은 코드 계층 구조를 구성하기 위해 들여쓰기를 사용하거나 화살표 함수 표현식을 사용하는 것을 받아들이지 않습니다. 그들에게는 기능 키워드와 중괄호가 없는 구성이 보기에 좋지 않습니다.
목록 구문 분석은 매우 강력하지만 너무 간결합니다. 복잡한 JavaScript 프로그램을 구성하는 데 익숙한 사람들에게는 이 표현이 익숙하지 않습니다.
간단히 말하면, 다른 사람에게 CoffeeScript 사용법을 배우도록 강요할 수는 없습니다. JavaScript는 충분히 강력하므로 주의만 기울이면 JavaScript를 사용하여 작업을 잘 수행할 수 있습니다. CoffeeScript를 시도하려는 사람들에게도 격려의 자세를 주어야 합니다. 그들은 혁신과 변화를 추구하는 전사들입니다. CoffeeScript는 정말 시도해 볼 가치가 있고 크기도 매우 작아서 완전히 익히는 것도 어렵지 않습니다.
저는 개인적으로 팀 내 CoffeeScript 구현에 대해 보수적인 견해를 가지고 있습니다. 팀이 처음부터 CoffeeScript를 사용했다면 더 좋았을 것입니다. CoffeeScript에서 JavaScript로 전환하는 경우 주의하세요. 한 가지 가능한 방법은 먼저 소규모 프로젝트에서 CoffeeScrip을 사용해 작동 방식을 확인하는 것입니다.
개인의 경우 제한이 없습니다. 당신이 정말로 그것을 좋아한다면, 그것을 위해 가십시오. CoffeeScript를 사용하여 스크립트를 작성하고, 자신만의 웹사이트를 구축하고, 일부 가젯을 만들 수 있습니다.
위 콘텐츠는 편집자가 소개한 CoffeeScrip을 사용하여 자바스크립트 코드를 작성하는 아름다운 방법입니다.