PHP เป็นภาษาที่อยู่มานาน แต่ยังออกเวอร์ชันใหม่ทุกปี (รายการเวอร์ชันบน php.watch) ตั้งแต่เพิ่ม type ให้เช็คได้เข้มขึ้น ไปจนถึง JIT ที่ช่วยเรื่องความเร็ว PHP 8 ก็เพิ่ม syntax ที่ทำให้โค้ดสั้นและอ่านง่ายขึ้นหลายตัว
โพสต์นี้หยิบ syntax เหล่านั้นมาเทียบกับ JavaScript ทีละตัว ว่าฝั่ง JavaScript มีหรือยัง ถ้ายังไม่มี เราเขียนแทนกันยังไง ตัวอย่างฝั่ง PHP เช็คกับ PHP 8.4 แล้ว
1. Named arguments ส่งค่าตามชื่อ parameter (JavaScript ไม่มี)
สมมุติเรามีฟังก์ชันแบบนี้
function savePost(Post $post, bool $isSticky = false, ?string $imagePath = null): void
{
// ...
}
ถ้าอยากส่งแค่ $post กับ $imagePath เราเรียกด้วยชื่อ parameter ได้เลย (RFC)
savePost(post: $post, imagePath: $path);
// ผสมกันก็ได้ ใส่แบบตามลำดับไว้ก่อน แล้วตามด้วยแบบมีชื่อ
savePost($post, imagePath: $path);
ไม่ต้องส่ง $isSticky เลย PHP ใช้ค่า default ให้เอง มีประโยชน์มากกับฟังก์ชันที่รับ parameter สัก 4-5 ตัวขึ้นไป ซึ่งเราจำลำดับไม่ค่อยได้ว่าตัวไหนอยู่ตำแหน่งที่เท่าไหร่
JavaScript ยังไม่มี syntax นี้ ถ้าอยากข้าม parameter ตรงกลาง ส่ง undefined ไปแทน แล้ว JavaScript จะใช้ค่า default ของตัวนั้น (MDN) แต่ส่ง null ไม่ได้ เพราะ null นับเป็นค่าที่ส่งมาจริง
savePost(post, undefined, 'path/to/image.jpg');
อีกทางที่ใช้กันมาตลอดคือให้ฟังก์ชันรับ object แล้วแตกค่าด้วย destructuring อ่านแล้วใกล้เคียง named arguments แต่ต้องออกแบบฟังก์ชันให้รับ object ตั้งแต่แรก และคนเรียกต้องห่อค่าเป็น object ทุกครั้ง
function savePost({ post, isSticky = false, imagePath = null }) {
// ...
}
savePost({ post, imagePath: 'path/to/image.jpg' });
2. match เลือกค่าตามเงื่อนไขในนิพจน์เดียว (JavaScript ไม่มี)
match เป็น syntax ของ PHP 8 ที่ผมใช้บ่อยที่สุดตัวหนึ่ง ใช้แทน switch หรือ array lookup ได้แทบทุกที่ (คู่มือ PHP)
$color = match ($state) {
'draft' => 'gray',
'active', 'complete', 'done' => 'primary',
default => 'secondary',
};
match คืนค่าออกมาให้เก็บใส่ตัวแปรได้ทันที เทียบแบบ === และถ้าไม่มี arm ไหนตรงและไม่มี default PHP จะ throw UnhandledMatchError ให้ อ่านรายละเอียดต่อได้ในโพสต์ syntax ใหม่ของ PHP 8
JavaScript มีแค่ switch ซึ่งเป็น statement คืนค่าไม่ได้ และต้องใส่ break เองทุก case (MDN)
let color;
switch (state) {
case 'draft':
color = 'gray';
break;
case 'active':
case 'complete':
case 'done':
color = 'primary';
break;
default:
color = 'secondary';
}
ถ้าเทียบค่าคงที่ตรง ๆ แบบนี้ เขียนเป็น object lookup แล้วใช้ ?? ใส่ค่า default จะสั้นกว่า
const colors = { draft: 'gray', active: 'primary', complete: 'primary', done: 'primary' };
const color = colors[state] ?? 'secondary';
ฝั่ง TC39 มี proposal pattern matching ที่ใช้คำว่า match เหมือนกัน แต่ตอนนี้ยังอยู่แค่ Stage 1 ยังไม่มีเบราว์เซอร์ไหนใช้ได้ และ syntax ยังเปลี่ยนได้อีกมาก
3. Constructor property promotion ประกาศ property ใน constructor ทีเดียว (JavaScript ไม่มี)
ใน PHP 8 ใส่ visibility หรือ readonly หน้า parameter ของ constructor แล้ว PHP จะสร้าง property และกำหนดค่าให้เลย (คู่มือ PHP)
class Money
{
public function __construct(
public readonly int $amount,
public readonly string $currency = 'THB',
) {}
}
$price = new Money(1500);
$price->currency; // 'THB'
JavaScript ไม่มีแบบนี้ ต้องกำหนดค่าให้ this เองทีละตัว
class Money {
constructor(amount, currency = 'THB') {
this.amount = amount;
this.currency = currency;
}
}
ถ้าเขียน TypeScript จะมี parameter properties ที่หน้าตาคล้ายของ PHP แต่เป็นความสามารถของ TypeScript ไม่ใช่ JavaScript
4. Nullsafe operator ?-> ตัวนี้ JavaScript มี ?. แล้ว
ถ้าเรียกเมธอดต่อกันหลายชั้น แล้วชั้นไหนคืน null มา PHP จะ error ตอนเรียกเมธอดถัดไป ใส่ ?-> แล้ว PHP จะหยุดทั้ง chain และคืน null ทันทีที่เจอ null (RFC)
$company = auth()->user()?->getDepartment()?->getCompany();
ไม่ว่า user() หรือ getDepartment() จะคืน null โค้ดก็ไม่ error และ $company เป็น null
ฉบับแรกของโพสต์นี้เขียนไว้ว่า JavaScript ไม่มีแบบนี้ ซึ่งผิด JavaScript มี optional chaining ?. มาตั้งแต่ ES2020 (TC39) และใช้ได้ในเบราว์เซอร์หลักทุกตัวตั้งแต่กลางปี 2020 (MDN) ก่อน PHP 8.0 ออกเสียอีก
const company = auth().user()?.getDepartment()?.getCompany();
สองตัวนี้ต่างกันนิดหน่อย
?.ของ JavaScript หยุดเมื่อเจอทั้งnullและundefinedแล้วคืนundefinedส่วน?->ของ PHP คืนnull- JavaScript ใช้
?.กับ array และการเรียกฟังก์ชันได้ด้วย เช่นitems?.[0]หรือcallback?.()ส่วน PHP ใช้?->ได้กับ object เท่านั้น ถ้าเป็น array ใช้??แทน เช่น$data['user']['name'] ?? null
ส่วน null coalescing ?? ทั้งสองภาษามีเหมือนกัน PHP มีตั้งแต่ 7.0 และ JavaScript มีตั้งแต่ ES2020 (MDN)
แล้ว PHP 8.5 มีอะไรที่ JavaScript ยังไม่มีอีก
PHP 8.5 (ออกเมื่อ 20 พ.ย. 68) เพิ่ม pipe operator |> ส่งค่าทางซ้ายเข้าฟังก์ชันทางขวาต่อกันเป็นทอด ๆ อ่านจากซ้ายไปขวาได้เลย ไม่ต้องซ้อนวงเล็บหลายชั้น (RFC)
$slug = $title
|> trim(...)
|> strtolower(...)
|> (fn (string $text): string => str_replace(' ', '-', $text));
JavaScript มี proposal pipeline operator อยู่เหมือนกัน แต่ยังอยู่ Stage 2 ยังใช้จริงไม่ได้ ส่วนฝั่ง PHP ต้องใช้ PHP 8.5 ขึ้นไป ถ้าโปรเจกต์ยังอยู่ PHP 8.3 หรือ 8.4 (Laravel 13 รองรับตั้งแต่ 8.3) ยังใช้ |> ไม่ได้
เทียบกันทั้งหมด
| ฟีเจอร์ | PHP | JavaScript |
|---|---|---|
| Named arguments | 8.0 | ไม่มี ใช้ object กับ destructuring แทน |
match |
8.0 | ไม่มี pattern matching ยังอยู่ Stage 1 |
| Constructor property promotion | 8.0 | ไม่มี มีใน TypeScript |
Nullsafe ?-> / ?. |
8.0 | มีตั้งแต่ ES2020 |
Null coalescing ?? |
7.0 | มีตั้งแต่ ES2020 |
| Pipe operator | 8.5 | ไม่มี proposal ยังอยู่ Stage 2 |






