Node Master
اگر در NodeJS برای وب سرورتون Auth service مینویسید و اگر فرایند Auth شما بر پایه password باشد. معمولا به این صورت مقایسه پسورد صورت میگیرید. if (hashed_pass_from_db === hashed_pass_from_input) { console.log("sucess") } این تکه کد یک مشکل امنیتی خطرناک…
معمولا وقتی راجع به امنیت و crypto در #NodeJS پست میزارم خیلی استقبال میشه. امروز میخوایم راجع به public key signture صحبت کنیم. با مثال میریم جلو.
در حقیقت crypto module همونطور که میدونید یک api روی Openssl هست پس ما به تمام قابلیت های openssl دسترسی داریم. حتی اگر دوست داشتید میتونید self signed tls certificate درست کنید و برای تست در web server هاتون استفاده کنید.
اینجا خیلی وارد جزیات نمیشیم و خیلی کلی گویی میشه تا طولانی نشه. جدا از encryption یک مفهوم دیگ داریم به اسم sign کردن که این دوتا معمولا در کنار هم استفاده میشن. حالا سوال پیش میاد sign چیست؟
قرار هست یک نفر یک دیتا رو برای شما ارسال کنه و میخواید مطمن بشید که فقط اون براتون فرستاده. مثل نامه های دولتی که با مهر دولتی روی نامه ثابت میشه که از طرف دولت هست و شما مطمن هستی که دولت فرستاده. حالا برای کاری شبیه به این میشه این کار رو کرد.
اول یک rsa public and private key تولید میکنید و حالا یکجایی ذخیره میکنید. با الگوریتم های دیگ هم میشه ولی خب من اینجا دوست داشتم RSA استفاده کنم.
بعد شما data خام رو بعد از serialization و encode کردن با private key ( یا همون مهر دولتی ) امضا میکنید. بعد شخصی که اونور نشسته و شما میخواید دیتا رو براش بفرستید حالا از طریق http tcp یا websocket یا هرچیزی باید public key رو داشته باشه.
شخصی که این دیتا رو دریافت کرده با استفاده از public key و verify function میتونه ثابت کنه که این دیتا توسط شما امضا شده و هیچ تغییری نکرده. دقیقا یجورایی مثل jwt token هست.
حالا این فرایند کلی بود. شما دقیقا میتونید ساختاری شبیه به jwt رو خودتون این مدلی دستی بسازید.
به طور خلاصه jwt شامل ۳ بخش با این ساختار است header.payload.signature حالا شما اگر هدر رو در نظر نگیری با استفاده از تکه کد پایین میتونین شبیه به jwt رو بسازید با ساختار payload.signature.
این دقیق خود jwt نیست اون یکم پیچدگی بیشتر داره. ولی درکل حدف آشنایی با این موضوع بود جزیات خیلیی بیشتر بود که من واقعا خیلی خلاصه کردم و خیلی چیزا رو اصلا اشاره نکردیم که خیلی مهم بودن.
حالا در پست های آینده قطعا این موضوعات هم برسی میکنیم.
#Tip
import crypto from "node:crypto";
const { privateKey, publicKey } = crypto.generateKeyPairSync("rsa", {
modulusLength: 2048,
});
const ALGO = "RSA-SHA256";
const rawData = { username: "imanhpr", channel: "NodeMaster" };
const data = Buffer.from(JSON.stringify(rawData));
const signature = crypto.sign(ALGO, data, privateKey);
const verify = crypto.verify(ALGO, data, publicKey, signature);
console.log(verify);
در حقیقت crypto module همونطور که میدونید یک api روی Openssl هست پس ما به تمام قابلیت های openssl دسترسی داریم. حتی اگر دوست داشتید میتونید self signed tls certificate درست کنید و برای تست در web server هاتون استفاده کنید.
اینجا خیلی وارد جزیات نمیشیم و خیلی کلی گویی میشه تا طولانی نشه. جدا از encryption یک مفهوم دیگ داریم به اسم sign کردن که این دوتا معمولا در کنار هم استفاده میشن. حالا سوال پیش میاد sign چیست؟
قرار هست یک نفر یک دیتا رو برای شما ارسال کنه و میخواید مطمن بشید که فقط اون براتون فرستاده. مثل نامه های دولتی که با مهر دولتی روی نامه ثابت میشه که از طرف دولت هست و شما مطمن هستی که دولت فرستاده. حالا برای کاری شبیه به این میشه این کار رو کرد.
اول یک rsa public and private key تولید میکنید و حالا یکجایی ذخیره میکنید. با الگوریتم های دیگ هم میشه ولی خب من اینجا دوست داشتم RSA استفاده کنم.
بعد شما data خام رو بعد از serialization و encode کردن با private key ( یا همون مهر دولتی ) امضا میکنید. بعد شخصی که اونور نشسته و شما میخواید دیتا رو براش بفرستید حالا از طریق http tcp یا websocket یا هرچیزی باید public key رو داشته باشه.
شخصی که این دیتا رو دریافت کرده با استفاده از public key و verify function میتونه ثابت کنه که این دیتا توسط شما امضا شده و هیچ تغییری نکرده. دقیقا یجورایی مثل jwt token هست.
حالا این فرایند کلی بود. شما دقیقا میتونید ساختاری شبیه به jwt رو خودتون این مدلی دستی بسازید.
به طور خلاصه jwt شامل ۳ بخش با این ساختار است header.payload.signature حالا شما اگر هدر رو در نظر نگیری با استفاده از تکه کد پایین میتونین شبیه به jwt رو بسازید با ساختار payload.signature.
const jwtLike =
Buffer.from(JSON.stringify(rawData)).toString("base64") +
"." +
signature.toString("base64");
console.log(jwtLike);
این دقیق خود jwt نیست اون یکم پیچدگی بیشتر داره. ولی درکل حدف آشنایی با این موضوع بود جزیات خیلیی بیشتر بود که من واقعا خیلی خلاصه کردم و خیلی چیزا رو اصلا اشاره نکردیم که خیلی مهم بودن.
حالا در پست های آینده قطعا این موضوعات هم برسی میکنیم.
#Tip
👍10
امروز یک برنامه کلاسیک HelloWorld با استفاده از #webassembly module مینویسیم و import در #NodeJS صحبت میکنیم برای خودم خیلی باحال بود و تصور این که چه قدرتی این کار داره واقعا جذابه.
این که #NodeJS کند هست همه قبول داریم ولی خب اونقدری کند نیست که بگیم بد هست. حتی روی scale بزرگ هم جواب میده و مشکلی نیست ولی گاهی شاید بخواهیم قدرتش رو با ابزار های کمکی بیشتر کنیم. یکی از این راها استفاده از C++ N-API هست که میشه native module هایی که با CPP توسعه داده شدن رو استفاده کنیم و اصن کلا کل nodejs همین هست. تازگی ها api اومده که میتونیم کد های #rust هم bind کنیم که اسمش رو یادم نمیاد. معمولا این کارا رو زمانی انجام میدن که یک پروژه بزرگ روی nodejs هست و هزینه بازنویسی روی زبان های سریعتر مثل golang خیلی زیاد هست و ارزش نداره و با استفاده از این تکنیک ها قدرتش رو بیشتر میکنن. ( این که golang سریعتره دلیل بر بهتر بودن لزوما نیست ) از این موضوع بگذریم و بریم سر وقت مثال و کد.
اگر از #ESM استفاده میکنید قبلا بهتون گفته بودم که چطور json رو مستقیم import کنید بدون استفاده از fs.readfile و ... . یکی دیگه از ویژگی های #ESM قابلیت import کردن #WASM ماژول ها هست. WASM ها ماژول های نوشته شده با webassambly هست که سرعت near native داره که مقدمه کوچیکی بالا گفتم حالا بریم یکم مثال بزنیم. وقتی راجع به سرعت near native صحبت میکنیم شوخی نیست!
کلا با استفاده از تکنولوژی های زیادی میشه خروچی wasm گرفت از cpp و rust گرفته تا #AssamblyScript که یکچیز شبیه به #TypeScript هست ولی در اینجا ما از فرمتی به اسم #WAT یا که میشه WebAssambly Text Format استفاده میکنیم برای برنامه HelloWorld. حالا بریم با مثال صحبت کنیم.
جدا از syntax یکی از بزرگترین چالش هایی که اینجا داریم Memory management هست که در خام ترین حالت ممکن هست تقریبا و اصلا نمیشه اینجا کوچک ترین اشاره به جزیاتش کرد ولی خب خط اول (memory 1) به مقدار 64Kib یعنی 65536 حافظه خطی در اختیار شما قرار میده. (چالش اصلی همین خطی بودن حافظه و manage کردنش برای دیتا های دیگس.
حالا با استفاده از export memory خط بعد این قسمت از حافظه رو که از WebAssembly.Memory برای دسترسی در کد #nodejs میایم و export میکنیم.
بعد با استفاده از data روی خونه اول حافظه شروع میکنیم به نوشتن بایت های helloworld و مهمترین و جذاب ترین قسمتش که کنجکاوی به وجود میاره استفاده از "\00". اینجا میخوام یک سوال مطرح کنم برام توی کامنت بگید که چرا از "\00" استفاده شده ؟
بعد میایم یک فانکشن تعریف میکنیم که یک عدد i32 برمیگردونیم که آدرس اخرین خونه ای هست که hello world داخلش قرار داره یعنی از 0 شروع شده تا 14.
حالا باید این رو compile کنیم به wasm که ابزار های مختلف هست. میتونید این کد رو کپی کنید و از سایت https://webassembly.github.io/wabt/demo/wat2wasm/ استفاده کنید برای تست و خروجی wasm رو بگیرید.
حالا آمده ایم بریم برای بخش node.
ماژول کامپایل شده رو import میکنیم و دوتا export در کد wat میبینید. یکی memory که حافظه خام ما هست که تبدیل میکنیم به buffer ( بدون تبدیل هم میشد این کارا رو کرد ولی حال نداشتم :) )
بعد این buf ما 64kib هست درصورتی که ما فقط 14 byte از این رو میخوایم. با استفاده از export دوم یعنی فانکشن getTextOffset میایم این buf رو قیچی میکنیم و 14 byte که حاوی helloworld ما هست میگیریم و بعد با encode کردن به utf8 لاگ میگریم و تمام. حالا برای ران کردن میتونید این کار کنید.
دوستان توجه کنیدکه خیلی خیلی خلاصه کردم از اتفاق هایی که میوفته تا کوتاه بشه ولی زیر به صورت تیتر وار میگم.
- اول درمورد memory این که حالا برنامه ما اینجا کوچیک بود و زیاد مهم نیست ولی این که 64kib مموری بگیری و از 14 byte فقط استفاده کنی اصلا کار درستی نیست.
- دوم کلا حواسمون باید خیلی به encode شدن باید باشه
- سوم همون سوالی که بالا گفتم بهش فکر کنید
- چهارم اون خط تبدیل کردن به buffer نیاز نیست و راه های بهتری هست که وقت نداشتم برم دنبالشون و هدف فقط اشاره به این تکنولوژی بود.
این که #NodeJS کند هست همه قبول داریم ولی خب اونقدری کند نیست که بگیم بد هست. حتی روی scale بزرگ هم جواب میده و مشکلی نیست ولی گاهی شاید بخواهیم قدرتش رو با ابزار های کمکی بیشتر کنیم. یکی از این راها استفاده از C++ N-API هست که میشه native module هایی که با CPP توسعه داده شدن رو استفاده کنیم و اصن کلا کل nodejs همین هست. تازگی ها api اومده که میتونیم کد های #rust هم bind کنیم که اسمش رو یادم نمیاد. معمولا این کارا رو زمانی انجام میدن که یک پروژه بزرگ روی nodejs هست و هزینه بازنویسی روی زبان های سریعتر مثل golang خیلی زیاد هست و ارزش نداره و با استفاده از این تکنیک ها قدرتش رو بیشتر میکنن. ( این که golang سریعتره دلیل بر بهتر بودن لزوما نیست ) از این موضوع بگذریم و بریم سر وقت مثال و کد.
اگر از #ESM استفاده میکنید قبلا بهتون گفته بودم که چطور json رو مستقیم import کنید بدون استفاده از fs.readfile و ... . یکی دیگه از ویژگی های #ESM قابلیت import کردن #WASM ماژول ها هست. WASM ها ماژول های نوشته شده با webassambly هست که سرعت near native داره که مقدمه کوچیکی بالا گفتم حالا بریم یکم مثال بزنیم. وقتی راجع به سرعت near native صحبت میکنیم شوخی نیست!
کلا با استفاده از تکنولوژی های زیادی میشه خروچی wasm گرفت از cpp و rust گرفته تا #AssamblyScript که یکچیز شبیه به #TypeScript هست ولی در اینجا ما از فرمتی به اسم #WAT یا که میشه WebAssambly Text Format استفاده میکنیم برای برنامه HelloWorld. حالا بریم با مثال صحبت کنیم.
(module
(memory 1)
(export "memory" (memory 0))
(data (i32.const 0) "Hello, World!\n\00")
(func (export "getTextOffset") (result i32)
i32.const 14
return
)
)
جدا از syntax یکی از بزرگترین چالش هایی که اینجا داریم Memory management هست که در خام ترین حالت ممکن هست تقریبا و اصلا نمیشه اینجا کوچک ترین اشاره به جزیاتش کرد ولی خب خط اول (memory 1) به مقدار 64Kib یعنی 65536 حافظه خطی در اختیار شما قرار میده. (چالش اصلی همین خطی بودن حافظه و manage کردنش برای دیتا های دیگس.
حالا با استفاده از export memory خط بعد این قسمت از حافظه رو که از WebAssembly.Memory برای دسترسی در کد #nodejs میایم و export میکنیم.
بعد با استفاده از data روی خونه اول حافظه شروع میکنیم به نوشتن بایت های helloworld و مهمترین و جذاب ترین قسمتش که کنجکاوی به وجود میاره استفاده از "\00". اینجا میخوام یک سوال مطرح کنم برام توی کامنت بگید که چرا از "\00" استفاده شده ؟
بعد میایم یک فانکشن تعریف میکنیم که یک عدد i32 برمیگردونیم که آدرس اخرین خونه ای هست که hello world داخلش قرار داره یعنی از 0 شروع شده تا 14.
حالا باید این رو compile کنیم به wasm که ابزار های مختلف هست. میتونید این کد رو کپی کنید و از سایت https://webassembly.github.io/wabt/demo/wat2wasm/ استفاده کنید برای تست و خروجی wasm رو بگیرید.
حالا آمده ایم بریم برای بخش node.
import * as mywasm from "./mywasm.wasm";
const buf = Buffer.from(mywasm.memory.buffer);
const helloWorld = buf.subarray(0, mywasm.getTextOffset());
console.log(helloWorld.toString("utf-8"));
ماژول کامپایل شده رو import میکنیم و دوتا export در کد wat میبینید. یکی memory که حافظه خام ما هست که تبدیل میکنیم به buffer ( بدون تبدیل هم میشد این کارا رو کرد ولی حال نداشتم :) )
بعد این buf ما 64kib هست درصورتی که ما فقط 14 byte از این رو میخوایم. با استفاده از export دوم یعنی فانکشن getTextOffset میایم این buf رو قیچی میکنیم و 14 byte که حاوی helloworld ما هست میگیریم و بعد با encode کردن به utf8 لاگ میگریم و تمام. حالا برای ران کردن میتونید این کار کنید.
node --experimental-wasm-modules main.js
دوستان توجه کنیدکه خیلی خیلی خلاصه کردم از اتفاق هایی که میوفته تا کوتاه بشه ولی زیر به صورت تیتر وار میگم.
- اول درمورد memory این که حالا برنامه ما اینجا کوچیک بود و زیاد مهم نیست ولی این که 64kib مموری بگیری و از 14 byte فقط استفاده کنی اصلا کار درستی نیست.
- دوم کلا حواسمون باید خیلی به encode شدن باید باشه
- سوم همون سوالی که بالا گفتم بهش فکر کنید
- چهارم اون خط تبدیل کردن به buffer نیاز نیست و راه های بهتری هست که وقت نداشتم برم دنبالشون و هدف فقط اشاره به این تکنولوژی بود.
👍6
نکته خیلی مهم این که من هم wasm بلد نیستم و برای این هم وقت زیادی نزاشتم. در آینده بیشتر روی این تکنولوژی کار میکنم و کلا یک پست هم خواهیم داشت درمورد آینده و تحلیلی که من دارم درمورد چنتا تکنولوژی و اتفاق های اخیر در کل اکوسیستم.
#Tip #WebAssembly
#Tip #WebAssembly
👍1
آیا از #ESM ( Es Module ) میدونید چیه؟ استفاده میکنید؟
Anonymous Poll
62%
بله استفاده میکنم.
16%
فقط شنیدم. اما استفاده نمیکنم.
21%
نه اصلا نمیدونم چی هست و استفاده نمیکنم.
Node Master
یکی از دلایلی که خیلی #NodeJS بنظرم جذاب هست کتابخونه Buffer هست برام. console.log(Buffer.allocUnsafe(10000).toString("utf8")) این کد رو اجرا کنید متوجه حرفم میشید. نظرتون رو برام کامنت کنید. #Tip
دلیل این که این کد جذابه این موضوع هست که بعضی قسمت های #NodeJS دسترسی هایی خیلی نزدیک به زبانی مثل C بهت میده. و اون Api نزدیک به Api های low level داخل C هست.
نمونه دیگ از این موضوع میتونه وقتی باشه که یک فایل یا سوکت به صورت خام باز میکنید و یکدونه file denoscriptor دریافت میکنید.
نمونه چیزی که میگم.
نمونه دیگ از این موضوع میتونه وقتی باشه که یک فایل یا سوکت به صورت خام باز میکنید و یکدونه file denoscriptor دریافت میکنید.
نمونه چیزی که میگم.
fs.open('/Users/joe/test.txt', 'r', (err, fd) => {
// fd is our file denoscriptor
});
اینجا fd به معنی file denoscriptor هست که یک عدد integer هست که از سمت سیستم عامل مشخص میکنه مربوط به چه فایلی هست که قراره عملیات روش انجام بشه.👍4
در خیلی از زبان های برنامه نویسی وقتی با threading یا حتی asyncio در حال انجام عملیات concurrent هستید نیاز دارید به صورت تستی برنامه رو مثلا برای چند ثانیه بلاک ( یا همون sleep ) مثال های زیر توجه کنید.
نکته خیلی مهم : اگر در برنامه production مجبور شدید که به صورت دستی مثل مثال های بالا مثلا 2 ثانیه برنامه رو sleep کنید به این معنی هست که یکجای کار اشتباهی کردید و این عملیات به هیچ عنوان نباید در کد production مگر دلیل خیلی خیلی قانع کننده استفاده بشه. معمولا برای تست کردن mock request و شبیه سازی مثلا network latency استفاده میشه.
حالا اگر بخوایم این کار رو داخل #NodeJS انجام بدیم معادل sleep رو نداریم و یکجورایی دستی باید خودمون بسازیم. قدیما از این روش استفاده میشد.
این مدل کد تقریبا sleep های بالا رو شبیه سازی میکنه. البته این نکته رو بگم دوتا کد بالا sync هستن و برای سادگی concurncy رو وارد نکردم هرچند به عنوان مثال در python ما asyncio.sleep هم داریم که این تکه کد بیشتر معادل asyncio.sleep در پایتون هست.
حالا یک روش تمیز تر در #NodeJS برای این کار هست که میتونید استفاده کنید که کدش رو در پایین میبینید.
در کتاب خانه "timers/promises" برای timer func های nodejs معادل promise base async api هست که بدردتون میخوره یک موردش اینجاس.
یک استفاده خیلی خوب از این مدل تایمر ها این هست که اگر یک فانکشن بزرگ دارید که event loop رو بلاک میکنه میتونید تیکه تیکه انجامش بدید که event loop هم بلاک نشه.
البته این جمله بالا اگر دقت کنید خیلی کاربردش شبیهه به generator function ها هست. ( این موضوع که چه ربطی به generator function ها داره خارج از بحث امروز هست دوست داشتید خودتون برید مطالعه کنید. )
#Tip
import time
time.sleep(2)
print("hello")
package main
import (
"fmt"
"time"
)
func main() {
time.Sleep(time.Second * 2)
fmt.Println("Hello")
}
نکته خیلی مهم : اگر در برنامه production مجبور شدید که به صورت دستی مثل مثال های بالا مثلا 2 ثانیه برنامه رو sleep کنید به این معنی هست که یکجای کار اشتباهی کردید و این عملیات به هیچ عنوان نباید در کد production مگر دلیل خیلی خیلی قانع کننده استفاده بشه. معمولا برای تست کردن mock request و شبیه سازی مثلا network latency استفاده میشه.
حالا اگر بخوایم این کار رو داخل #NodeJS انجام بدیم معادل sleep رو نداریم و یکجورایی دستی باید خودمون بسازیم. قدیما از این روش استفاده میشد.
async function asynctask() {
await new Promise((reslove) => {
setTimeout(() => {
reslove();
}, 2000);
});
console.log("hello");
}
asynctask();این مدل کد تقریبا sleep های بالا رو شبیه سازی میکنه. البته این نکته رو بگم دوتا کد بالا sync هستن و برای سادگی concurncy رو وارد نکردم هرچند به عنوان مثال در python ما asyncio.sleep هم داریم که این تکه کد بیشتر معادل asyncio.sleep در پایتون هست.
حالا یک روش تمیز تر در #NodeJS برای این کار هست که میتونید استفاده کنید که کدش رو در پایین میبینید.
import { setTimeout } from "timers/promises";
async function asynctask() {
await setTimeout(2000);
console.log("hello");
}
asynctask();در کتاب خانه "timers/promises" برای timer func های nodejs معادل promise base async api هست که بدردتون میخوره یک موردش اینجاس.
یک استفاده خیلی خوب از این مدل تایمر ها این هست که اگر یک فانکشن بزرگ دارید که event loop رو بلاک میکنه میتونید تیکه تیکه انجامش بدید که event loop هم بلاک نشه.
البته این جمله بالا اگر دقت کنید خیلی کاربردش شبیهه به generator function ها هست. ( این موضوع که چه ربطی به generator function ها داره خارج از بحث امروز هست دوست داشتید خودتون برید مطالعه کنید. )
#Tip
👍6
واقعا باورم نمیشه که ۴۰۰ نفر شدیم. خیلی خوشحالم که مطالب براتون مفید هست❤️🎉
دوستان اگر انتقادی دارید یا ایده برای برسی و یادگیری اینجا بزارید.
از این فرصت استفاده کنم یک نکته هم بگم که دوستانی که یک سری موضوعات رو پیشنهاد دادن من همه رو یاداشت کردم و در ادامه صحبت خواهیم کرد. اگر تا حالا صحبتی نشده بخاطر این هست که مطالب عمیقی بودن و نمیشه در قالب پست تلگرامی عمیق شد.
باز هم از همه دوستان تشکر میکنم و واقعا خیلی خوشحالم که از مطالب استفاده میکنید.🎉❤️
یک گروه هم مدتی هست داریم که با بچه ها راجع به این نکات صحبت میکنیم و کلا رفع مشکلات دوست داشتید میتونید جوین بشید.
https://news.1rj.ru/str/NodeMasterGP
دوستان اگر انتقادی دارید یا ایده برای برسی و یادگیری اینجا بزارید.
از این فرصت استفاده کنم یک نکته هم بگم که دوستانی که یک سری موضوعات رو پیشنهاد دادن من همه رو یاداشت کردم و در ادامه صحبت خواهیم کرد. اگر تا حالا صحبتی نشده بخاطر این هست که مطالب عمیقی بودن و نمیشه در قالب پست تلگرامی عمیق شد.
باز هم از همه دوستان تشکر میکنم و واقعا خیلی خوشحالم که از مطالب استفاده میکنید.🎉❤️
یک گروه هم مدتی هست داریم که با بچه ها راجع به این نکات صحبت میکنیم و کلا رفع مشکلات دوست داشتید میتونید جوین بشید.
https://news.1rj.ru/str/NodeMasterGP
👍14
Node Master
در ادامه مبحث Cluster Module و IPC یکی از مرسوم ترین روش های IPC استفاده از Signal برای فرستادن یک سری پیام های خاص به یک Process هست. به عنوان مثال از معروف ترین Singal ها که همیشه استفاده میکنید و ممکن هست بهشون توجه نکرده باشید SIGINT و SIGKILL میباشد.…
یک کنجکاوی که مدتی هست یاداشت کردم تا بعد درموردش عمیق تر بشم این بخش از داکیومنت #NodeJS هست. که لینکش پایین هست.
https://nodejs.org/docs/latest/api/child_process.html#subprocesssendmessage-sendhandle-options-callback
نوشته : "When the child process is a Node.js instance, these messages can be received via the 'message' event."
این موضوع در سطح سیستم عامل خیلی برام جالبه که چطور دقیق متوجه میشه که این child process یک node process هست.
روش های مختلفی به ذهن من میاد مثل
- یک فرایند handshake صورت میگیره که بنظرم پیچیدس.
- شاید از روی command متوجه میشه.
کلا این موضوع که child process که Node app هست رو خاص در نظر میگیره و یک سری api اضافی بهت میده خیلی نکته جالب و جذابی هست. چون این که چطور این اتفاق میافته بنظرم چالش سخت و جذابیه.
https://nodejs.org/docs/latest/api/child_process.html#subprocesssendmessage-sendhandle-options-callback
نوشته : "When the child process is a Node.js instance, these messages can be received via the 'message' event."
این موضوع در سطح سیستم عامل خیلی برام جالبه که چطور دقیق متوجه میشه که این child process یک node process هست.
روش های مختلفی به ذهن من میاد مثل
- یک فرایند handshake صورت میگیره که بنظرم پیچیدس.
- شاید از روی command متوجه میشه.
کلا این موضوع که child process که Node app هست رو خاص در نظر میگیره و یک سری api اضافی بهت میده خیلی نکته جالب و جذابی هست. چون این که چطور این اتفاق میافته بنظرم چالش سخت و جذابیه.
👍7
دوستان.
برای نصب #NodeJS روی سیستم خودتون سعی کنید از nvm استفاده کنید.
فرایند آپدیت کردن و نگهداری همزمان ورژن های مختلف #NodeJS رو براتون خیلی راحت میکنه.
https://github.com/nvm-sh/nvm
برای نصب #NodeJS روی سیستم خودتون سعی کنید از nvm استفاده کنید.
فرایند آپدیت کردن و نگهداری همزمان ورژن های مختلف #NodeJS رو براتون خیلی راحت میکنه.
https://github.com/nvm-sh/nvm
GitHub
GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash noscript to manage multiple active node.js versions
Node Version Manager - POSIX-compliant bash noscript to manage multiple active node.js versions - nvm-sh/nvm
👍5
مدتی توییتر فعالیت ندارم ولی این تراژدی #اسنپ_فود خیلی ناراحتم کرد.
در این توییت درسی که به نظرم باید از این داستان بگیریم رو گفتم. لینکش آخره و ادامه یکم صحبت خودمونی هست :)
تمام موضوعاتی که اینجا صحبت میکنیم کنار این یک حرف کنار.
خواهش میکنم دوستان اگر Backend کد میزنید فقط Framework developer نباشید.
عمیق بشید تا برسید به assembly.
به واسطه framework ها بچه های backend خیلی سطحی شدن و علاقه ای به عمیق تر شدن در مسائل کمتر دارن.
بخاطر همین جامعه Backend از جامعه هکر ها از نظر فنی عقب افتاده. سعی کنید خودتون رو برسونید.
من خودم هم مثل بقیه هستم و خیلی عقب افتادم ولی همیشه در همین مسیر داشتم حرکت میکردم ولی الان خیلی ضرورتش بیشتر شد برام.
توییت هم خوشحال میشم اشتراک بزارید.
https://twitter.com/imanhpr_media/status/1741489206382211530?t=Q1vxgBK1DaomODK0ZkuKEg&s=19
در این توییت درسی که به نظرم باید از این داستان بگیریم رو گفتم. لینکش آخره و ادامه یکم صحبت خودمونی هست :)
تمام موضوعاتی که اینجا صحبت میکنیم کنار این یک حرف کنار.
خواهش میکنم دوستان اگر Backend کد میزنید فقط Framework developer نباشید.
عمیق بشید تا برسید به assembly.
به واسطه framework ها بچه های backend خیلی سطحی شدن و علاقه ای به عمیق تر شدن در مسائل کمتر دارن.
بخاطر همین جامعه Backend از جامعه هکر ها از نظر فنی عقب افتاده. سعی کنید خودتون رو برسونید.
من خودم هم مثل بقیه هستم و خیلی عقب افتادم ولی همیشه در همین مسیر داشتم حرکت میکردم ولی الان خیلی ضرورتش بیشتر شد برام.
توییت هم خوشحال میشم اشتراک بزارید.
https://twitter.com/imanhpr_media/status/1741489206382211530?t=Q1vxgBK1DaomODK0ZkuKEg&s=19
X (formerly Twitter)
ImanHpr (@imanhpr_media) on X
درسی که به نظرم باید از داستان هک #اسنپ_فود بگیریم.
اول این که بچه های Backend به لطف framework ها در بازی امنیت خیلی از هکر ها عقب افتادن. ( نمونه خود من )
دوم این که حس میکنم این نتیجه مستقیم فرهنگ سازمانی هست که من حس میکنم اکثر شرکت ها دارن.
/1
اول این که بچه های Backend به لطف framework ها در بازی امنیت خیلی از هکر ها عقب افتادن. ( نمونه خود من )
دوم این که حس میکنم این نتیجه مستقیم فرهنگ سازمانی هست که من حس میکنم اکثر شرکت ها دارن.
/1
👍13👎4
یکبار داشتم تست مینوشتم و داشتم type ها رو assert میکردم که به این موضوع خوردم که چند ساعتی داشتم دنبالش میگشتم که داستان چیه و در نهایت متوجه شدم که اگر string رو با String class مستقیم بسازید typeof مربوط بهش میشه object و نه string.
دقیق یادم نمیاد که کد چی بود ولی مشکلش این typeof بود که object میشد و من انتظار داشتم string بشه.
#Tip
const text1 = new String("NodeMaster");
const text2 = "NodeMaster";
console.log(typeof text1); // object
console.log(typeof text2); // stringدقیق یادم نمیاد که کد چی بود ولی مشکلش این typeof بود که object میشد و من انتظار داشتم string بشه.
#Tip
👍7
Node Master
دوستان. برای نصب #NodeJS روی سیستم خودتون سعی کنید از nvm استفاده کنید. فرایند آپدیت کردن و نگهداری همزمان ورژن های مختلف #NodeJS رو براتون خیلی راحت میکنه. https://github.com/nvm-sh/nvm
اگر میخواید #NodeJS رو روی سیستم خودتون نصب کنید یک سری ابزار ها هست که اینکار رو برای شما راحت تر میکنه و قابلیت های بیشتری به شما میده.
- آپدیت کردن راحت تر
- داشتن چند ورژن همزمان و سویچ کردن
و ... . ۳ تا از این ابزار ها پایین هست من خودم از nvm استفاد میکنم ولی بعضی دوستان volta رو معرفی کردن. ویژگی خوب volta این هست که روی ویندوز هم کار میکنه ولی nvm فقط لینوکس هست فک کنم.
https://volta.sh/
یکی دیگ هم هست به اسم fnm که با rust نوشتن میتونید چک کنید.
https://github.com/Schniz/fnm
درکل همشون یک کار میکنن هرکدوم رو چک کنید و دوست داشتید استفاده کنید.
مرسی از @dev_a_loper بابت معرفی volta
- آپدیت کردن راحت تر
- داشتن چند ورژن همزمان و سویچ کردن
و ... . ۳ تا از این ابزار ها پایین هست من خودم از nvm استفاد میکنم ولی بعضی دوستان volta رو معرفی کردن. ویژگی خوب volta این هست که روی ویندوز هم کار میکنه ولی nvm فقط لینوکس هست فک کنم.
https://volta.sh/
یکی دیگ هم هست به اسم fnm که با rust نوشتن میتونید چک کنید.
https://github.com/Schniz/fnm
درکل همشون یک کار میکنن هرکدوم رو چک کنید و دوست داشتید استفاده کنید.
مرسی از @dev_a_loper بابت معرفی volta
volta.sh
Volta - The Hassle-Free JavaScript Tool Manager
Volta: Start your engines.
👍14
Node Master
گاهی اوقات در زمان توسعه برنامه نیاز است که از یک Object یک کپی ایجاد کنیم و Object اصلی رو به هیچ عنوان mutate نکنیم. برای کپی کردن object معمولا دو حالت دارد. - deep copy - shallow copy بزارید با مثال براتون تفاوت این دو مدل رو توضیح بدم. const user = {…
قبلا درمورد identity check صحبت خیلی کوتاهی کردیم که با استفاده از "===" میتونیم reference ها رو چک کنیم. فرض کنید ما دوتا object رو میخوایم مقایسه کنیم نه بر اساس reference ها بلکه براساس attr ها. اینجا "node:util" به کمک ما میاد.
دو obj که داریم با این که دقیقا یک شکل هستن ولی داخل دو خونه حافظه جدا هستن یعنی reference های متفاوت دارن. حالا با isdeepStrictEqual میتونیم این دوتا رو با هم چک کنیم که اگر کد رو اجرا کنید کاملا متوجه میشید داستان چیه.
دقیقا یک نسخه از همین فانکشن رو داخل "node:assert" داریم که لاجیکی که داره همین هست ولی بجای bool type به ما AssertionError برمیگردونه.
حالا سوال پیش میاد بنظرتون چرا باید دو مدل api برای یک لاجیک و خروجی ها متفاوت داشته باشیم؟
#Tip
#NodeJS
import util from "node:util";
const obj1 = { name: "NodeMaster" };
const obj2 = { name: "NodeMaster" };
console.log(util.isDeepStrictEqual(obj1, obj2));
console.log(obj1 === obj2);
دو obj که داریم با این که دقیقا یک شکل هستن ولی داخل دو خونه حافظه جدا هستن یعنی reference های متفاوت دارن. حالا با isdeepStrictEqual میتونیم این دوتا رو با هم چک کنیم که اگر کد رو اجرا کنید کاملا متوجه میشید داستان چیه.
دقیقا یک نسخه از همین فانکشن رو داخل "node:assert" داریم که لاجیکی که داره همین هست ولی بجای bool type به ما AssertionError برمیگردونه.
assert.deepStrictEqual(obj1, obj2);
util.isDeepStrictEqual(obj1, obj2);
حالا سوال پیش میاد بنظرتون چرا باید دو مدل api برای یک لاجیک و خروجی ها متفاوت داشته باشیم؟
#Tip
#NodeJS
👍8
سلام و ارادت دوستان. خیلی وقت بود میخواستم ویدیو بسازم و راجع به یک سری موضوعات صحبت کنم. البته این ویدیو بیشتر معرفی خودم و یکسری نکات درمورد چنل هست.
به زودی ویدیو های تکنیکال درمورد موضوعاتی که تو کانال داریم به صورت عمیق تر خواهیم داشت.
جا داره از همتون تشکر کنم و خوشحالم اگر مطالب براتون مفید بوده❤️
ممنون میشم این ویدیو هم ببینید.
https://youtu.be/znWtGcqHWbQ?si=IJDCOcPqDDJ_SeAF
به زودی ویدیو های تکنیکال درمورد موضوعاتی که تو کانال داریم به صورت عمیق تر خواهیم داشت.
جا داره از همتون تشکر کنم و خوشحالم اگر مطالب براتون مفید بوده❤️
ممنون میشم این ویدیو هم ببینید.
https://youtu.be/znWtGcqHWbQ?si=IJDCOcPqDDJ_SeAF
YouTube
سلام یوتیوب و دنیا !
اولین ویدیو یوتیوب من هست که درباره چنل تلگرامی که مدتی روش کار میکنم صحبت کردم.
و درمورد برنامه آینده این موضوعات.
https://news.1rj.ru/str/nodemaster
و درمورد برنامه آینده این موضوعات.
https://news.1rj.ru/str/nodemaster
👍15
Node Master
یکی از مشکلاتی که Node داشت و Deno سعی بر حل آن بود امنیت اجرای پکیج های 3rd party بود که اگر پکیجی بخواهد کارهایی از قبیل دسترسی به network یا خواندن و نوشتن دیتا روی disk انجام دهد شما باید به عنوان developer تایید کنید و اجازه دسترسی بدهید. و حالا در Node…
یک خبری چند روز پیش درمورد امنیت پکیج های NPM اومده بود که کره شمالی قصد دزدی از کیف پول های cryptocurrency ها با استفاده از پکیج آلوده داشته که میتونید جزیاتش رو از لینک زیر مطالعه کنید.
https://www.nodejs-security.com/blog/north-korea-malware-on-npm-and-ledger-connect-kit-crypto-heist
این دقیقا همون دلیلی هست که #Deno برای امنیت permission رو اضافه کرد و #NodeJS هم این قابلیت رو در حال حاظر به صورت experimental برای جلوگیری از این دسته مشکلات اضافه کرد.
خلاصه بگم. اگر پکیج اضافه میکنید به پروژه که دارید. چندین بار درمورد اون پکیج فکر کنید که آیا اصلا لازم دارید یا خیر.
نکته best practice : هرچقدر از پکیج های کمتری استفاده کنید زندگی راحت تری در نگهداری پروژه در طولانی مدت خواهید داشت.
#NodeWeekly
https://www.nodejs-security.com/blog/north-korea-malware-on-npm-and-ledger-connect-kit-crypto-heist
این دقیقا همون دلیلی هست که #Deno برای امنیت permission رو اضافه کرد و #NodeJS هم این قابلیت رو در حال حاظر به صورت experimental برای جلوگیری از این دسته مشکلات اضافه کرد.
خلاصه بگم. اگر پکیج اضافه میکنید به پروژه که دارید. چندین بار درمورد اون پکیج فکر کنید که آیا اصلا لازم دارید یا خیر.
نکته best practice : هرچقدر از پکیج های کمتری استفاده کنید زندگی راحت تری در نگهداری پروژه در طولانی مدت خواهید داشت.
#NodeWeekly
NodeJS Security & NodeJS Secure Coding
North Korea malware on npm and Ledger connect-kit crypto heist
North Korean state hackers compromise npm supply chain with malicious packages; crypto thieves exploit Ledger Connect kit library published to npm, stealing $600k before detected; incident highlights risks of uncontrolled open source usage and need for better…
👍3
در خیلی از زبان های برنامه نویسی مثل #Python #javanoscript #Golang و ... میبینیم که میگن فانکشن ها first class citizen function هستن. این موضوع خیلی میتونه تاثیر در برنامه های نوشته شده در زبان مورد نظر داشته باشه.
اصلا چرا بهشون میگیم first class citizen ؟
چیکار ها میتونیم انجام بدیم باهاشون؟
یکم راجع به این موضوع فکر کنید فردا راجع بهش صحبت خواهیم کرد.
https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
اصلا چرا بهشون میگیم first class citizen ؟
چیکار ها میتونیم انجام بدیم باهاشون؟
یکم راجع به این موضوع فکر کنید فردا راجع بهش صحبت خواهیم کرد.
https://developer.mozilla.org/en-US/docs/Glossary/First-class_Function
MDN Web Docs
First-class function - Glossary | MDN
A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function…
👍4
خب first class function یعنی چی؟
به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید.
این موضوع خیلی نکته قوی هست که کلا decorator pattern درمورد این موضوع هست. البته این موضوع فقط مربوط به فانکشن ها نیست و بلکه شما میتونید همین کار رو برای کلاس ها و attr ها هم انجام بدید.
یکم بخوایم به موضوع بهتر نگاه کنیم در اصل این کار یکی از تکنیک های پر استفاده در Metaprograming میباشد که در فریمورک ها خیلی پر استفاده هست. یکسری فریمورک ها مثل NestJS سنگین از این موضوع استفاده میکنند.
فرض کنید لیستی داریم از چهار فانکشن که ۴ عمل اصلی ریاضی رو انجام میدن.
همچین چیزی رو داخل کد هایی که روزمره استفاده میکنید ممکنه که نبینید. این موضوع منطقی هست استفاده از این تکنیکا ها کاربردهای خاصی دارند که کمتر در پروژه های saas بهشون نیاز میشه. ( به معنی صفر بودن استفاده نیست :) )
یک مثال یک خورده عملی تر در express میتونیم middleware بسازیم. فرض کنید میخوایم یک سری route رو محافظت کنیم که یک سری role خاص بتونن به اون دسترسی داشته باشن. در ساده ترین حالت ممکن این هست.
این مدل کد خیلی استفاده میشه. مزیتی که داره ساده و خوانا هست ولی عیب بزرگش scale نمیشه رفت. فرض کنید 100 تا role داریم. یعنی 100 فانکشن. نکته سخت داستان این هست که در route ها ما باید reference از فانکشن ها بدیم و نه call کنیم یکم دقیق تر بگم در اینجا express برای ما IOC (inversion of control) داره انجام میده و مجبورمون میکنه اینطور کد بزنیم.
دلیل این هم که نمیتونیم کاری کنیم این هست که ما در زمان compile time داریم adminUse و normalUse رو ایجاد میکنیم که باز دست ما رو میبنده. اگر بتونیم با code مثل بقیه data ها رفتار کنیم مشکل حل میشه یعنی در runtime فاکشن ایجاد کنیم نه compile time !
اگر بخوایم حرف بالا رو عملی کنیم این شکل میشه.
دقت کنید دوستان ما فانکشن رو invoke نمیکنیم و حالا در runtime داریم اون رو میسازیم. موضوع خیلی خیلی مهمی که باید برای پشت پرده این داستان بدونید Closure هست. فانکشن roleFactory در حقیقت وظیفه تولید function جدید در runtime دارد. حالا شما همین کار رو میتونید برای هرچیزی در #Javanoscript کنید.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
توجه داشته باشید این مثال production ready نیست و صرفا برای گرفتن دید درمورد این موضوع هست. این موضوع اینجا تموم نشده و در پست بعدی مثال دیگه ای میزنیم.
درمورد کاربرد های دیگه این موضوع فکر کنید و نظراتتون رو کامنت کنید.
#Tip
به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید.
این موضوع خیلی نکته قوی هست که کلا decorator pattern درمورد این موضوع هست. البته این موضوع فقط مربوط به فانکشن ها نیست و بلکه شما میتونید همین کار رو برای کلاس ها و attr ها هم انجام بدید.
یکم بخوایم به موضوع بهتر نگاه کنیم در اصل این کار یکی از تکنیک های پر استفاده در Metaprograming میباشد که در فریمورک ها خیلی پر استفاده هست. یکسری فریمورک ها مثل NestJS سنگین از این موضوع استفاده میکنند.
فرض کنید لیستی داریم از چهار فانکشن که ۴ عمل اصلی ریاضی رو انجام میدن.
const sum = (a, b) => a + b;
const division = (a, b) => a / b;
const multiply = (a, b) => a * b;
const minus = (a, b) => a - b;
const operators = [sum, division, multiply, minus];
operators.forEach((fn) => {
console.log(fn(6, 2));
});
همچین چیزی رو داخل کد هایی که روزمره استفاده میکنید ممکنه که نبینید. این موضوع منطقی هست استفاده از این تکنیکا ها کاربردهای خاصی دارند که کمتر در پروژه های saas بهشون نیاز میشه. ( به معنی صفر بودن استفاده نیست :) )
یک مثال یک خورده عملی تر در express میتونیم middleware بسازیم. فرض کنید میخوایم یک سری route رو محافظت کنیم که یک سری role خاص بتونن به اون دسترسی داشته باشن. در ساده ترین حالت ممکن این هست.
let app; // imagine it's an express instance. :)
// Dummy controller function.
const protectedLogic = () => {};
const ADMIN = "ADMIN";
const NORMAL = "NORMAL";
function adminUse(req, res, next) {
if (req.role === NORMAL) next();
}
function normalUse(req, res, next) {
if (req.role === ADMIN) next();
}
// Express routes.
app.get("/admin", adminUse, protectedLogic);
app.get("/user", normalUse, protectedLogic);
این مدل کد خیلی استفاده میشه. مزیتی که داره ساده و خوانا هست ولی عیب بزرگش scale نمیشه رفت. فرض کنید 100 تا role داریم. یعنی 100 فانکشن. نکته سخت داستان این هست که در route ها ما باید reference از فانکشن ها بدیم و نه call کنیم یکم دقیق تر بگم در اینجا express برای ما IOC (inversion of control) داره انجام میده و مجبورمون میکنه اینطور کد بزنیم.
دلیل این هم که نمیتونیم کاری کنیم این هست که ما در زمان compile time داریم adminUse و normalUse رو ایجاد میکنیم که باز دست ما رو میبنده. اگر بتونیم با code مثل بقیه data ها رفتار کنیم مشکل حل میشه یعنی در runtime فاکشن ایجاد کنیم نه compile time !
اگر بخوایم حرف بالا رو عملی کنیم این شکل میشه.
function roleFactroy(rank) {
return function (req, res, next) {
if (req.role === rank) next();
};
}
// Express routes.
app.get("/admin", roleFactroy(ADMIN), protectedLogic);
app.get("/user", roleFactroy(NORMAL), protectedLogic);
دقت کنید دوستان ما فانکشن رو invoke نمیکنیم و حالا در runtime داریم اون رو میسازیم. موضوع خیلی خیلی مهمی که باید برای پشت پرده این داستان بدونید Closure هست. فانکشن roleFactory در حقیقت وظیفه تولید function جدید در runtime دارد. حالا شما همین کار رو میتونید برای هرچیزی در #Javanoscript کنید.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
توجه داشته باشید این مثال production ready نیست و صرفا برای گرفتن دید درمورد این موضوع هست. این موضوع اینجا تموم نشده و در پست بعدی مثال دیگه ای میزنیم.
درمورد کاربرد های دیگه این موضوع فکر کنید و نظراتتون رو کامنت کنید.
#Tip
MDN Web Docs
Closures - JavaScript | MDN
A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope. In JavaScript, closures are created every time…
👍18
https://www.linkedin.com/posts/mohammad-esfandiari-ab069322a_%D8%A7%D8%B3%D8%AA%D8%A7%D8%B1%D8%AA%D8%A7%D9%BE-%D9%85%D9%81%DB%8C%D8%AF-backend-developer-%D8%AC%D8%B0%D8%A8-%D9%85%DB%8C%DA%A9%D9%86%D8%AF-activity-7145778735194009600-UVNL?utm_source=share&utm_medium=member_andro
#Work
#Work
Linkedin
Mohammad Esfandiari on LinkedIn: استارتاپ مفید Backend developer جذب میکند.
مهارت های فنی:
مسلط به:…
مهارت های فنی:
مسلط به:…
استارتاپ مفید Backend developer جذب میکند.
مهارت های فنی:
مسلط به: Express js
مسلط به: Node js
مسلط به: Nest js
مسلط به : Graph QL
مسلط به : Mongo DB
مسلط…
مهارت های فنی:
مسلط به: Express js
مسلط به: Node js
مسلط به: Nest js
مسلط به : Graph QL
مسلط به : Mongo DB
مسلط…
Node Master
خب first class function یعنی چی؟ به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید. این موضوع خیلی نکته قوی هست…
خب هنوز یک قدم میخوایم پا رو فراتر بزاریم و class رو در runtime بسازیم. اول این که در #Javanoscript کلاس ها در حقیقت همون فانکشن ها هستن و صرفا کلمه class یک syntactic sugar روی نسخه ES5 هست. کلمه class در آپدیت معروف ES6 به #Javanoscript اضافه شد.
یعنی این دوتا باهم برابر هستند.
قدیما وقتی میخواستن کلاس بسازن از syntax به شکل User2 استفاده میکردن. اسم این مدل ES5 function constructors ولی چون شکل قشنگی نداشت class syntax رو اضاف کردن. هردو اینا دقیق برابر هستن یعنی در اصل class syntax اون پشت تبدیل میشه به مدل User2 اینطور تصور کنید.
اونجا که کامنت کردم خیلی میتونست ساده تر باشه. دیدم فرصت خوبی هست که بحثش رو بیارم وسط. بحث خیلی مهمی هست و یکی از خاصیت های زبان های dynamic type هست. فکر کنید راجع بهش کامنت بزارید در ادامه درموردش صحبت خواهیم کرد.
میریم سر اصل مطلب. اگر دقت کنید قدیما وقتی میخواستن کلاس بسازن از function استفاده میکردن ( منطقی یا غیرمنطقی بودن این موضوع یک بحث دیگس که کاری نداریم) پست قبلی یاد گرفتیم که function ها در حقیقت first class هستن و میتونیم هرکاری باهاشون کنیم! آفرین دقیقه نکته داستان همینه. به این دلیل که کلاس ها تبدیل میشن به ES5 function constructors اون پشت پس تمامی کارایی که قبل میتونستیم کنیم مجازه. بریم برای مثال.
مثال یکم فرانتی هست. ما کلاس رو در runtime ایجاد کردیم و براش private attr ست کردیم و اگر این کد رو اجرا کنید میبینید هم getter به درستی کار میکنه و هم شما مستقیم دسترسی به color ندارید. نکته جالب اینه دوباره برا مثال خوردیم به pattern بالا که گفتم. بهش فکر کنید.
یک نکته ای که وجود داره اینه که این ها anonymous class هستن و اسم ندارند. کد زیر رو اجرا کنید
حالا اگر بخوایم name رو به صورت HardCode بزنیم داخل btnFactory قشنگ در نمیاد چون همه کلاس ها یک اسم خواهند داشت. اگر anonymous هم باشیم ساعت های سختی رو برای debug خواهیم داشت.
تا همینجا برای این پست کافیه پست بعدی یکم عمیق تر میشیم در metaprograming.
یعنی این دوتا باهم برابر هستند.
// Syntactic Sugar
class User {
constructor(name, last_name) {
this.name = name;
this.last_name = last_name;
}
printFullName() {
console.log(this.name + " " + this.last_name);
}
}
function User2(name, last_name) {
this.name = name;
this.last_name = last_name;
}
User2.prototype.printFullName = function () {
console.log(this.name + " " + this.last_name);
};
// Think about this part. 🤔
const users = [new User("iman", "hpr"), new User2("iman", "hpr")];
users.forEach((user) => console.log(user.printFullName()));
قدیما وقتی میخواستن کلاس بسازن از syntax به شکل User2 استفاده میکردن. اسم این مدل ES5 function constructors ولی چون شکل قشنگی نداشت class syntax رو اضاف کردن. هردو اینا دقیق برابر هستن یعنی در اصل class syntax اون پشت تبدیل میشه به مدل User2 اینطور تصور کنید.
اونجا که کامنت کردم خیلی میتونست ساده تر باشه. دیدم فرصت خوبی هست که بحثش رو بیارم وسط. بحث خیلی مهمی هست و یکی از خاصیت های زبان های dynamic type هست. فکر کنید راجع بهش کامنت بزارید در ادامه درموردش صحبت خواهیم کرد.
میریم سر اصل مطلب. اگر دقت کنید قدیما وقتی میخواستن کلاس بسازن از function استفاده میکردن ( منطقی یا غیرمنطقی بودن این موضوع یک بحث دیگس که کاری نداریم) پست قبلی یاد گرفتیم که function ها در حقیقت first class هستن و میتونیم هرکاری باهاشون کنیم! آفرین دقیقه نکته داستان همینه. به این دلیل که کلاس ها تبدیل میشن به ES5 function constructors اون پشت پس تمامی کارایی که قبل میتونستیم کنیم مجازه. بریم برای مثال.
function buttonFactory(color) {
return class {
#color = color;
get color() {
return this.#color;
}
show() {
console.log("Button is " + this.#color);
}
};
}
const BlueBtnCls = buttonFactory("blue");
const RedBtnCls = buttonFactory("red");
const blueBtn = new BlueBtnCls();
const redBtn = new RedBtnCls();
// Here we go agin 😉. Think about it one more 🤔
const btns = [blueBtn, redBtn].forEach((btn) => btn.show());مثال یکم فرانتی هست. ما کلاس رو در runtime ایجاد کردیم و براش private attr ست کردیم و اگر این کد رو اجرا کنید میبینید هم getter به درستی کار میکنه و هم شما مستقیم دسترسی به color ندارید. نکته جالب اینه دوباره برا مثال خوردیم به pattern بالا که گفتم. بهش فکر کنید.
یک نکته ای که وجود داره اینه که این ها anonymous class هستن و اسم ندارند. کد زیر رو اجرا کنید
const BlueBtnCls = buttonFactory("blue");
console.log(BlueBtnCls) // out : [class (anonymous)]
console.log(BlueBtnCls.name)حالا اگر بخوایم name رو به صورت HardCode بزنیم داخل btnFactory قشنگ در نمیاد چون همه کلاس ها یک اسم خواهند داشت. اگر anonymous هم باشیم ساعت های سختی رو برای debug خواهیم داشت.
تا همینجا برای این پست کافیه پست بعدی یکم عمیق تر میشیم در metaprograming.
👍13