جاوااسکریپت: سوءتفاهم‌برانگیزترین زبان برنامه‌نویسی دنیا

این مطلب ترجمه ای آزاد است از:

;#x27;s Most Misunderstood Programming Language

مطلبی نوشتهی داگلاس کراکفرد. کراکفرد (طبق نوشتهی ویکیپدیا) در روند توسعه ی جاوااسکریپت، قالب JSON و خیلی چیزای دیگه دخیل بوده. این مقاله در سال 2001 نوشته شده و یه مقاله ی کلاسیک محسوب می شه. برای همین هم ترجمه اش سخته هم ممکنه بعضی چیزاش الان دیگه درست نباشه.

در اصل این مقاله رو ترجمه کردم و توضیح دادم تا بعدش بتونم «معرفی دوباره جاوااسکریپت» رو بخونم و بفهمم.

Douglas Crockford
Douglas Crockford


مقدمه

جاوااسکریپت، که با نامهایی مانند Mocha، LiveScript، JScript و ECMAScript نیز شناخته میشود، یکی از محبوبترین زبانهای برنامهنویسی در جهان است. تقریباً هر رایانهٔ شخصی در دنیا حداقل یک مفسر جاوااسکریپت دارد که نصب شده و در حال استفاده است. محبوبیت جاوااسکریپت کاملاً مدیون نقش آن به عنوان زبان اسکریپتنویسی وب جهانی (WWW) است.

با وجود این محبوبیت، افراد کمی میدانند که جاوااسکریپت در واقع یک زبان برنامهنویسی شیگرا، پویا و همهمنظورهی بسیار خوب است. چطور چنین چیزی میتواند یک راز باشد؟ چرا این زبان تا این حد بد فهمیده شده است؟

نام

پیشوند «Java-» این تصور را القا میکند که جاوااسکریپت به نوعی با Java مرتبط است؛ گویی زیرمجموعهای یا نسخهای ضعیفتر از آن است. به نظر میرسد این نام عمداً برای ایجاد سردرگمی انتخاب شده باشد، و از دل سردرگمی، سوءتفاهم زاده میشود.
جاوااسکریپت، Java تفسیرشده نیست — Java، خودش تفسیرشده است. جاوااسکریپت زبان متفاوتی است.

جاوااسکریپت از نظر نحوی شباهتهایی با Java دارد، همانطور که Java به C شباهت دارد. اما جاوااسکریپت به همان اندازه که Java زیرمجموعهٔ C نیست، زیرمجموعهٔ Java نیست. در کاربردهایی که Java (که در گذشته Oak نام داشت) برایشان طراحی شده بود، جاوااسکریپت حتی بهتر عمل میکند.

جاوااسکریپت در شرکت Sun Microsystems، یعنی زادگاه Java، توسعه نیافت؛ بلکه در شرکت Netscape توسعه یافت. نام اولیهٔ آن LiveScript بود، اما ظاهراً آن نام بهاندازهی کافی گیجکننده نبود!

پسوند «-Script» نیز این برداشت را بهوجود میآورد که جاوااسکریپت یک زبان برنامهنویسی واقعی نیست، و زبانهای اسکریپتنویسی کمتر از زبانهای برنامهنویسی هستند. اما این موضوع در واقع بیشتر به تخصصی بودن مربوط است. در مقایسه با C، جاوااسکریپت کارایی را فدای قدرت بیانی و پویایی میکند.

زبان Lisp در لباس C

نحو شبیه به C در جاوااسکریپت — مانند آکولادها و حلقهٔ for پرزحمت — باعث میشود آن را یک زبان رویهای معمولی ببینیم. اما این دیدگاه گمراهکننده است، چرا که جاوااسکریپت بیشتر با زبانهای تابعی نظیر Lisp و Scheme اشتراک دارد تا با C یا Java.
در جاوااسکریپت به جای لیستها از آرایهها استفاده میشود و به جای property listها، از اشیاء. توابع در آن موجودیت درجهیک هستند. دارای closures است. و میتوان از «لَمبدا»ها استفاده کرد بدون آنکه در پرانتزها غرق شد.

قالببندی (Typecasting)

جاوااسکریپت برای اجرا در مرورگر Netscape Navigator طراحی شد. موفقیت آن در این پلتفرم باعث شد به تجهیز پیشفرض تقریباً تمام مرورگرهای وب تبدیل شود. این اتفاق منجر به نوعی قالببندی فرهنگی شد. جاوااسکریپت در دنیای زبانهای برنامهنویسی، حکم George Reeves را دارد (اشاره به بازیگری که نقش سوپرمن را بازی میکرد و همیشه به آن شناخته میشد).
جاوااسکریپت برای بسیاری از کاربردهای غیر وب نیز بهخوبی مناسب است.

هدف متحرک (Moving Target)

نسخههای اولیهٔ جاوااسکریپت بسیار ضعیف بودند. فاقد مدیریت استثناء، توابع داخلی، و وراثت بودند. اما در نسخههای کنونی، این زبان اکنون یک زبان شیءگرا و کامل است. با این حال، بسیاری از قضاوتها دربارهٔ این زبان بر اساس نسخههای اولیه و نابالغ آن شکل گرفتهاند.

کمیتهٔ ECMA که مسئول توسعهٔ این زبان است، در حال افزودن ویژگیهای جدید است که گرچه نیت خوبی دارند، اما یکی از بزرگترین مشکلات زبان را تشدید میکنند: تعداد بیش از حد نسخهها. این موضوع موجب سردرگمی شده است.

خطاهای طراحی

هیچ زبان برنامهنویسیای بینقص نیست. جاوااسکریپت نیز خطاهای طراحی خاص خود را دارد، مانند استفادهٔ چندمنظوره از عملگر + برای هم جمع و هم الحاق (به همراه تبدیل نوع خودکار).
دستور with نیز مستعد خطاست و باید از آن اجتناب کرد. سیاستهای مربوط به کلمات رزروشده بیشازحد سختگیرانه هستند. درج خودکار نقطهویرگول یک اشتباه بزرگ بود، همینطور نحوهٔ نوشتن regexها. این اشتباهات موجب ایجاد خطاهای برنامهنویسی شدهاند و اعتبار طراحی کلی زبان را زیر سوال بردهاند.

خوشبختانه بسیاری از این مشکلات را میتوان با استفاده از یک برنامه lint خوب کاهش داد.

طراحی کلی زبان در واقع بسیار مستحکم است. بهطور شگفتانگیزی، کمیته ECMAScript ظاهراً علاقهای به رفع این مشکلات ندارد — شاید آنها بیشتر به ایجاد مشکلات جدید علاقهمندند!

پیادهسازیهای بد

برخی از نسخههای اولیهٔ جاوااسکریپت دارای اشکالات جدی بودند. این مسئله تأثیر منفی روی شهرت زبان گذاشت. از آن بدتر، این پیادهسازیها داخل مرورگرهایی قرار گرفته بودند که خودشان نیز بسیار پر از اشکال بودند.

کتابهای بد

تقریباً تمام کتابهایی که دربارهٔ جاوااسکریپت نوشته شدهاند، ضعیف هستند. این کتابها حاوی خطا، مثالهای بد، و ترویج شیوههای نادرست برنامهنویسی هستند.
ویژگیهای مهم زبان اغلب یا بد توضیح داده شدهاند یا کاملاً حذف شدهاند.
من دهها کتاب جاوااسکریپت را بررسی کردهام و تنها یکی را توصیه میکنم:
(نسخه پنجم) نوشتهٔ David Flanagan
(نکته برای نویسندگان: اگر کتاب خوبی نوشتهاید، لطفاً یک نسخه برای بررسی برای من بفرستید.)

استاندارد زیر سطح

مشخصات رسمی زبان توسط ECMA منتشر میشود. این سند کیفیت بسیار پایینی دارد؛ خواندن و درک آن سخت است. همین مسئله به مشکل کتابهای بد کمک کرده، چرا که نویسندگان نتوانستهاند از آن برای بهبود درک خود استفاده کنند.
کمیتهٔ TC39 و ECMA باید از این بابت بسیار شرمسار باشند.

آماتورها

بیشتر افرادی که با جاوااسکریپت کدنویسی میکنند، برنامهنویس حرفهای نیستند. آنها آموزش و انضباط لازم برای نوشتن برنامههای خوب را ندارند.
با این وجود، قدرت بیانی جاوااسکریپت آنقدر بالاست که همین افراد نیز میتوانند کارهای مفیدی با آن انجام دهند. این امر باعث شده جاوااسکریپت شهرتی پیدا کند مبنی بر اینکه فقط برای آماتورها مناسب است و برای برنامهنویسی حرفهای مناسب نیست — که البته چنین چیزی حقیقت ندارد.

شیءگرایی

آیا جاوااسکریپت شیءگرا است؟
این زبان دارای اشیائی است که میتوانند دادهها و متدهایی که روی آن دادهها عمل میکنند را در خود داشته باشند. اشیاء میتوانند اشیاء دیگر را نیز شامل شوند.
جاوااسکریپت کلاس ندارد، اما سازندهها (constructors) دارد که نقش کلاس را ایفا میکنند — حتی در نگهداری متغیرها و متدهای کلاس. این زبان وراثت مبتنی بر کلاس ندارد، اما وراثت مبتنی بر prototype دارد.

دو روش اصلی برای ساخت سیستمهای شیءگرا وجود دارد:

  • وراثت (is-a)
  • ترکیب (has-a)
    جاوااسکریپت از هر دو روش پشتیبانی میکند، اما به دلیل ماهیت پویا، در روش ترکیب عملکرد بسیار خوبی دارد.

برخی معتقدند که چون جاوااسکریپت پنهانسازی اطلاعات (Information Hiding) ندارد — یعنی اشیاء نمیتوانند متغیر یا متد خصوصی داشته باشند — پس شیءگرا نیست.
اما در واقع، جاوااسکریپت میتواند متغیرها و متدهای خصوصی داشته باشد. (برای دیدن روش آن اینجا کلیک کنید!)
البته، افراد کمی این را میدانند؛ چون جاوااسکریپت، بیشترین سوءتفاهم را در بین زبانهای برنامهنویسی دارد.

برخی دیگر نیز معتقدند جاوااسکریپت چون از وراثت پشتیبانی نمیکند، شیءگرا نیست. اما واقعیت این است که جاوااسکریپت نهتنها از وراثت کلاسیک پشتیبانی میکند، بلکه از الگوهای متنوع بازاستفادهٔ کد نیز پشتیبانی دارد.