JavaScript

ایونٹ ڈیلیگیشن کی وضاحت کریں

ایونٹ ڈیلیگیشن ایک تکنیک ہے جس میں ایونٹ لسنرز کو پیرنٹ عنصر میں شامل کیا جاتا ہے بجائے اس کے کہ انہیں ذیلی عناصر میں شامل کیا جائے۔ DOM میں ایونٹ کے بلبلہ اوپر آنے کی وجہ سے جب بھی ذیلی عناصر پر ایونٹ متحرک ہوگا تو لسنر فائر ہوگا۔ اس تکنیک کے فوائد یہ ہیں:

  • میموری کی جگہ کم ہو جاتی ہے کیونکہ پیرنٹ عنصر پر صرف ایک ہی ہینڈلر کی ضرورت ہوتی ہے، بجائے اس کے کہ ہر ذیلی عنصر پر ایونٹ ہینڈلر منسلک کرنا پڑے۔
  • ہٹائے گئے عناصر سے ہینڈلر کو غیر پابند کرنے اور نئے عناصر کے لیے ایونٹ کو پابند کرنے کی ضرورت نہیں ہے۔

جاوا اسکرپٹ میں 'this' کیسے کام کرتا ہے وضاحت کریں

'this' کی کوئی سادہ وضاحت نہیں ہے؛ یہ جاوا اسکرپٹ کے سب سے الجھن والے تصورات میں سے ایک ہے۔ ایک سرسری وضاحت یہ ہے کہ 'this' کی قدر اس بات پر منحصر ہے کہ فنکشن کو کیسے کال کیا جاتا ہے۔ میں نے 'this' کے بارے میں آن لائن بہت سی وضاحتیں پڑھی ہیں، اور مجھے [ارناوا اگروال] کی وضاحت سب سے واضح لگی۔ درج ذیل قواعد لاگو ہوتے ہیں:

  1. اگر فنکشن کو کال کرتے وقت 'new' کی ورڈ استعمال کیا جاتا ہے تو فنکشن کے اندر 'this' ایک بالکل نیا آبجیکٹ ہوتا ہے۔
  2. اگر 'apply'، 'call'، یا 'bind' کو کسی فنکشن کو کال/تخلیق کرنے کے لیے استعمال کیا جاتا ہے، تو فنکشن کے اندر 'this' وہ آبجیکٹ ہے جو دلیل کے طور پر پاس کیا جاتا ہے۔
  3. اگر کسی فنکشن کو ایک میتھڈ کے طور پر کال کیا جاتا ہے، جیسے 'obj.method()'—'this' وہ آبجیکٹ ہے جس کا فنکشن ایک پراپرٹی ہے۔
  4. اگر کسی فنکشن کو آزاد فنکشن کال کے طور پر بلایا جاتا ہے، یعنی اسے اوپر موجود کسی بھی حالت کے بغیر بلایا گیا تھا، تو 'this' عالمی آبجیکٹ ہوتا ہے۔ براؤزر میں، یہ 'window' آبجیکٹ ہے۔ اگر سخت موڈ ('use strict') میں ہو، تو 'this' عالمی آبجیکٹ کے بجائے 'undefined' ہوگا۔
  5. اگر اوپر کے متعدد قواعد لاگو ہوتے ہیں، تو جو قاعدہ اونچا ہے وہ جیت جائے گا اور 'this' کی قدر کو سیٹ کرے گا۔
  6. اگر فنکشن ایک ES2015 ایرو فنکشن ہے، تو یہ اوپر کے تمام قواعد کو نظر انداز کرتا ہے اور تخلیق کے وقت اپنے گردونواح کی گنجائش کی 'this' قدر حاصل کرتا ہے۔

گہرائی سے وضاحت کے لیے، ان کا [میڈیم پر مضمون] ضرور دیکھیں۔

کیا آپ اس بات کی ایک مثال دے سکتے ہیں کہ ES6 میں 'this' کے ساتھ کام کرنے کے طریقوں میں سے ایک کیسے تبدیل ہوا ہے؟

ES6 آپ کو [ایرو فنکشنز] استعمال کرنے کی اجازت دیتا ہے جو [ان کلوزنگ لغوی گنجائش] کا استعمال کرتے ہیں۔ یہ عام طور پر آسان ہوتا ہے، لیکن کالر کو '.call' یا '.apply' کے ذریعے سیاق و سباق کو کنٹرول کرنے سے روکتا ہے — اس کے نتیجے میں 'jQuery' جیسی لائبریری آپ کے ایونٹ ہینڈلر فنکشنز میں 'this' کو صحیح طریقے سے پابند نہیں کرے گی۔ اس طرح، بڑے پرانے ایپلی کیشنز کو ری فیکٹر کرتے وقت اسے ذہن میں رکھنا ضروری ہے۔

وضاحت کریں کہ پروٹوٹائپل وراثت کیسے کام کرتی ہے

تمام جاوا اسکرپٹ آبجیکٹس میں 'Object.create(null)' کے ساتھ بنائے گئے آبجیکٹس کے علاوہ ایک 'proto' پراپرٹی ہوتی ہے، جو ایک اور آبجیکٹ کا حوالہ ہے، جسے آبجیکٹ کا 'پروٹوٹائپ' کہا جاتا ہے۔ جب کسی آبجیکٹ پر کسی پراپرٹی تک رسائی حاصل کی جاتی ہے اور اگر وہ پراپرٹی اس آبجیکٹ پر نہیں ملتی، تو جاوا اسکرپٹ انجن آبجیکٹ کے 'proto' کو دیکھتا ہے، اور 'proto' کے 'proto' کو، اور اسی طرح، جب تک اسے کسی ایک 'proto' پر تعریف شدہ پراپرٹی نہ مل جائے یا جب تک وہ پروٹوٹائپ چین کے آخر تک نہ پہنچ جائے۔ یہ رویہ کلاسیکی وراثت کی نقالی کرتا ہے، لیکن یہ دراصل [وراثت سے زیادہ ڈیلیگیشن] ہے۔

پروٹوٹائپل وراثت کی مثال

// پیرنٹ آبجیکٹ کنسٹرکٹر۔ function Animal(name) { this.name = name; } // پیرنٹ آبجیکٹ کے پروٹوٹائپ میں ایک میتھڈ شامل کریں۔ Animal.prototype.makeSound = function () { console.log('The ' + this.constructor.name + ' makes a sound.'); }; // چائلڈ آبجیکٹ کنسٹرکٹر۔ function Dog(name) { Animal.call(this, name); // پیرنٹ کنسٹرکٹر کو کال کریں۔ } // چائلڈ آبجیکٹ کے پروٹوٹائپ کو پیرنٹ کے پروٹوٹائپ پر سیٹ کریں۔ Object.setPrototypeOf(Dog.prototype, Animal.prototype); // چائلڈ آبجیکٹ کے پروٹوٹائپ میں ایک میتھڈ شامل کریں۔ Dog.prototype.bark = function () { console.log('Woof!'); }; // Dog کی ایک نئی مثال بنائیں۔ const bolt = new Dog('Bolt'); // چائلڈ آبجیکٹ پر میتھڈز کو کال کریں۔ console.log(bolt.name); // 'Bolt' bolt.makeSound(); // 'The Dog makes a sound.' bolt.bark(); // 'Woof!'

قابل ذکر باتیں یہ ہیں:

  • '.makeSound' Dog پر تعریف شدہ نہیں ہے، لہذا انجن پروٹوٹائپ چین پر چڑھتا ہے اور ورثہ میں ملے 'Animal' سے '.makeSound' کو تلاش کرتا ہے۔
  • وراثت چین بنانے کے لیے 'Object.create' کا استعمال اب تجویز نہیں کیا جاتا ہے۔ اس کے بجائے 'Object.setPrototypeOf' استعمال کریں۔

آپ AMD بمقابلہ CommonJS کے بارے میں کیا سوچتے ہیں؟

دونوں ایک ماڈیول سسٹم کو لاگو کرنے کے طریقے ہیں، جو ES2015 کے آنے تک جاوا اسکرپٹ میں مقامی طور پر موجود نہیں تھا۔ CommonJS ہم وقت ساز ہے جبکہ AMD (Asynchronous Module Definition) ظاہر ہے غیر ہم وقت ساز ہے۔ CommonJS کو سرور سائیڈ کی ترقی کو مدنظر رکھتے ہوئے ڈیزائن کیا گیا ہے جبکہ AMD، ماڈیولز کی غیر ہم وقت ساز لوڈنگ کے لیے اپنی حمایت کے ساتھ، براؤزرز کے لیے زیادہ ہے۔

مجھے AMD syntax کافی وضاحتی معلوم ہوتا ہے اور CommonJS اس طرز کے قریب ہے جس میں آپ دیگر زبانوں میں امپورٹ اسٹیٹمنٹس لکھیں گے۔ زیادہ تر وقت، مجھے AMD غیر ضروری معلوم ہوتا ہے، کیونکہ اگر آپ نے اپنی تمام جاوا اسکرپٹ کو ایک مربوط بنڈل فائل میں پیش کیا تو آپ غیر ہم وقت ساز لوڈنگ کی خصوصیات سے فائدہ نہیں اٹھا پائیں گے۔ اس کے علاوہ، CommonJS syntax نوڈ ماڈیولز لکھنے کے طرز کے قریب ہے اور کلائنٹ سائیڈ اور سرور سائیڈ جاوا اسکرپٹ کی ترقی کے درمیان سوئچ کرتے وقت کم سیاق و سباق کی تبدیلی کا اوور ہیڈ ہوتا ہے۔

مجھے خوشی ہے کہ ES2015 ماڈیولز کے ساتھ، جس میں ہم وقت ساز اور غیر ہم وقت ساز دونوں لوڈنگ کے لیے سپورٹ ہے، ہم آخر کار صرف ایک ہی طریقہ پر قائم رہ سکتے ہیں۔ اگرچہ یہ براؤزرز اور نوڈ میں پوری طرح سے رول آؤٹ نہیں ہوا ہے، ہم ہمیشہ اپنے کوڈ کو تبدیل کرنے کے لیے ٹرانسپائلرز استعمال کر سکتے ہیں۔

وضاحت کریں کہ درج ذیل IIFE کے طور پر کیوں کام نہیں کرتا ہے: 'function foo(){ }();'۔ اسے صحیح طریقے سے IIFE بنانے کے لیے کیا تبدیل کرنے کی ضرورت ہے؟

IIFE کا مطلب Immediately Invoked Function Expressions ہے۔ جاوا اسکرپٹ پارسر 'function foo(){ }();' کو 'function foo(){ }' اور '();' کے طور پر پڑھتا ہے، جہاں سابقہ ایک function declaration ہے اور مؤخر الذکر (پیرانتھیسز کا ایک جوڑا) ایک فنکشن کو کال کرنے کی کوشش ہے لیکن کوئی نام مخصوص نہیں ہے، لہذا یہ 'Uncaught SyntaxError: Unexpected token )' کو پھینک دیتا ہے۔

اسے ٹھیک کرنے کے دو طریقے ہیں جن میں مزید پیرانتھیسز شامل کرنا شامل ہے: '(function foo(){ })()' اور '(function foo(){ }())'۔ وہ بیانات جو 'function' سے شروع ہوتے ہیں انہیں function declarations سمجھا جاتا ہے؛ اس فنکشن کو '()' کے اندر لپیٹنے سے، یہ ایک function expression بن جاتا ہے جسے بعد میں اگلے '()' کے ساتھ چلایا جا سکتا ہے۔ یہ فنکشنز عالمی گنجائش میں ظاہر نہیں ہوتے اور اگر آپ کو جسم کے اندر اپنے آپ کو حوالہ دینے کی ضرورت نہیں ہے تو آپ اس کا نام بھی چھوڑ سکتے ہیں۔

آپ 'void' آپریٹر بھی استعمال کر سکتے ہیں: 'void function foo(){ }();'۔ بدقسمتی سے، اس طرح کے نقطہ نظر میں ایک مسئلہ ہے۔ دی گئی اظہار کی تشخیص ہمیشہ 'undefined' ہوتی ہے، لہذا اگر آپ کا IIFE فنکشن کچھ بھی واپس کرتا ہے، تو آپ اسے استعمال نہیں کر سکتے۔ ایک مثال:

const foo = void (function bar() { return 'foo'; })(); console.log(foo); // undefined

ایک متغیر کے درمیان کیا فرق ہے جو: 'null'، 'undefined' یا undeclared ہے؟ آپ ان میں سے کسی بھی حالت کو کیسے چیک کریں گے؟

Undeclared متغیرات اس وقت بنائے جاتے ہیں جب آپ کسی شناخت کنندہ کو کوئی قدر تفویض کرتے ہیں جو پہلے 'var'، 'let' یا 'const' کا استعمال کرتے ہوئے نہیں بنایا گیا تھا۔ Undeclared متغیرات عالمی طور پر، موجودہ گنجائش سے باہر تعریف کیے جائیں گے۔ سخت موڈ میں، جب آپ کسی undeclared متغیر کو تفویض کرنے کی کوشش کریں گے تو ایک 'ReferenceError' پھینکا جائے گا۔ Undeclared متغیرات اتنے ہی برے ہیں جتنے عالمی متغیرات برے ہیں۔ ان سے ہر قیمت پر بچیں! انہیں چیک کرنے کے لیے، ان کے استعمال کو ایک 'try'/'catch' بلاک میں لپیٹیں۔

function foo() { x = 1; // سخت موڈ میں ReferenceError پھینکتا ہے } foo(); console.log(x); // 1

ایک متغیر جو 'undefined' ہے وہ ایک ایسا متغیر ہے جسے اعلان کیا گیا ہے، لیکن کوئی قدر تفویض نہیں کی گئی ہے۔ یہ 'undefined' قسم کا ہے۔ اگر کوئی فنکشن اسے چلانے کے نتیجے میں کوئی قدر واپس نہیں کرتا ہے تو اسے کسی متغیر کو تفویض کیا جاتا ہے، متغیر کی قدر بھی 'undefined' ہوتی ہے۔ اسے چیک کرنے کے لیے، سخت مساوات ('===') آپریٹر یا 'typeof' کا استعمال کرتے ہوئے موازنہ کریں جو 'undefined' سٹرنگ دے گا۔ یاد رکھیں کہ آپ کو چیک کرنے کے لیے خلاصہ مساوات آپریٹر کا استعمال نہیں کرنا چاہیے، کیونکہ اگر قدر 'null' ہو تو یہ بھی 'true' واپس کرے گا۔

var foo; console.log(foo); // undefined console.log(foo === undefined); // true console.log(typeof foo === 'undefined'); // true console.log(foo == null); // true. غلط، اسے چیک کرنے کے لیے استعمال نہ کریں! function bar() {} var baz = bar(); console.log(baz); // undefined

ایک متغیر جو 'null' ہے اسے واضح طور پر 'null' قدر تفویض کی گئی ہوگی۔ یہ کوئی قدر کی نمائندگی نہیں کرتا اور اس لحاظ سے 'undefined' سے مختلف ہے کہ اسے واضح طور پر تفویض کیا گیا ہے۔ 'null' کو چیک کرنے کے لیے، صرف سخت مساوات آپریٹر کا استعمال کرتے ہوئے موازنہ کریں۔ یاد رکھیں کہ اوپر کی طرح، آپ کو چیک کرنے کے لیے خلاصہ مساوات آپریٹر ('==') کا استعمال نہیں کرنا چاہیے، کیونکہ اگر قدر 'undefined' ہو تو یہ بھی 'true' واپس کرے گا۔

var foo = null; console.log(foo === null); // true console.log(typeof foo === 'object'); // true console.log(foo == undefined); // true. غلط، اسے چیک کرنے کے لیے استعمال نہ کریں!

ایک ذاتی عادت کے طور پر، میں کبھی بھی اپنے متغیرات کو undeclared یا unassigned نہیں چھوڑتا۔ میں انہیں اعلان کرنے کے بعد واضح طور پر 'null' تفویض کروں گا اگر میں انہیں ابھی استعمال کرنے کا ارادہ نہیں رکھتا ہوں۔ اگر آپ اپنے ورک فلو میں ایک لینٹر استعمال کرتے ہیں، تو یہ عام طور پر یہ بھی چیک کر سکے گا کہ آپ undeclared متغیرات کا حوالہ نہیں دے رہے ہیں۔

ایک کلوژر کیا ہے، اور آپ اسے کیسے/کیوں استعمال کریں گے؟

ایک کلوژر ایک فنکشن اور اس لغوی ماحول کا امتزاج ہے جس کے اندر وہ فنکشن اعلان کیا گیا تھا۔ لفظ 'لغوی' اس حقیقت کا حوالہ دیتا ہے کہ لغوی اسکوپنگ اس جگہ کا استعمال کرتی ہے جہاں سورس کوڈ میں ایک متغیر کو اعلان کیا جاتا ہے تاکہ یہ تعین کیا جا سکے کہ وہ متغیر کہاں دستیاب ہے۔ کلوژرز وہ فنکشنز ہیں جنہیں بیرونی (انکلوزنگ) فنکشن کے متغیرات تک رسائی حاصل ہوتی ہے — اسکوپ چین حتیٰ کہ بیرونی فنکشن واپس آنے کے بعد بھی۔

آپ اسے کیوں استعمال کریں گے؟

  • ڈیٹا کی رازداری / کلوژرز کے ساتھ نجی طریقوں کی نقل کرنا۔ عام طور پر [ماڈیول پیٹرن] میں استعمال ہوتا ہے۔
  • [جزوی ایپلی کیشنز یا کڑیینگ]۔

کیا آپ '.forEach' لوپ اور '.map()' لوپ کے درمیان بنیادی فرق بیان کر سکتے ہیں اور آپ ایک کو دوسرے کے مقابلے میں کیوں منتخب کریں گے؟

دونوں کے درمیان فرق کو سمجھنے کے لیے، آئیے دیکھتے ہیں کہ ہر فنکشن کیا کرتا ہے۔

'forEach'

  • ایک صف میں عناصر کے ذریعے دہراتا ہے۔
  • ہر عنصر کے لیے ایک کال بیک کو چلایا جاتا ہے۔
  • کوئی قدر واپس نہیں کرتا۔
const a = [1, 2, 3]; const doubled = a.forEach((num, index) => { // num اور/یا index کے ساتھ کچھ کریں۔ }); // doubled = undefined

'map'

  • ایک صف میں عناصر کے ذریعے دہراتا ہے۔
  • ہر عنصر پر فنکشن کو کال کرکے ہر عنصر کو ایک نئے عنصر میں 'میپ' کرتا ہے، جس کے نتیجے میں ایک نئی صف بناتا ہے۔
const a = [1, 2, 3]; const doubled = a.map((num) => { return num * 2; }); // doubled = [2, 4, 6]

'.forEach' اور '.map()' کے درمیان بنیادی فرق یہ ہے کہ '.map()' ایک نئی صف واپس کرتا ہے۔ اگر آپ کو نتیجہ کی ضرورت ہے، لیکن اصلی صف کو تبدیل نہیں کرنا چاہتے، تو '.map()' واضح انتخاب ہے۔ اگر آپ کو صرف ایک صف پر دہرانا ہے، تو 'forEach' ایک اچھا انتخاب ہے۔

گمنام فنکشنز کے لیے ایک عام استعمال کا کیس کیا ہے؟

انہیں IIFEs میں استعمال کیا جا سکتا ہے تاکہ کچھ کوڈ کو مقامی دائرہ کار کے اندر encapsule کیا جا سکے تاکہ اس میں اعلان کردہ متغیرات عالمی دائرہ کار میں نہ پھیلیں۔

(function () { // کچھ کوڈ یہاں۔ })();

ایک کال بیک کے طور پر جو ایک بار استعمال ہوتا ہے اور اسے کہیں اور استعمال کرنے کی ضرورت نہیں ہوتی۔ کوڈ زیادہ خود ساختہ اور پڑھنے کے قابل دکھائی دے گا جب ہینڈلرز کو ان کو کال کرنے والے کوڈ کے اندر ہی تعریف کیا جائے گا، بجائے اس کے کہ فنکشن باڈی کو تلاش کرنے کے لیے کہیں اور تلاش کرنا پڑے۔

setTimeout(function () { console.log('Hello world!'); }, 1000);

فعال پروگرامنگ تعمیرات یا لوڈیش (کال بیکس کی طرح) کے دلائل۔

const arr = [1, 2, 3]; const double = arr.map(function (el) { return el * 2; }); console.log(double); // [2, 4, 6]

آپ اپنے کوڈ کو کیسے منظم کرتے ہیں؟ (ماڈیول پیٹرن، کلاسیکی وراثت؟)

ماضی میں، میں نے اپنے ماڈلز کے لیے بیکبون استعمال کیا ہے جو ایک زیادہ OOP نقطہ نظر کی حوصلہ افزائی کرتا ہے، بیکبون ماڈلز بناتا ہے اور ان سے میتھڈز منسلک کرتا ہے۔

ماڈیول پیٹرن اب بھی بہت اچھا ہے، لیکن آج کل، میں ری ایکٹ/ریڈکس استعمال کرتا ہوں جو فلکس آرکیٹیکچر پر مبنی یک طرفہ ڈیٹا فلو کا استعمال کرتا ہے۔ میں اپنے ایپ کے ماڈلز کو سادہ اشیاء کا استعمال کرتے ہوئے ظاہر کروں گا اور ان اشیاء کو ہیر پھیر کرنے کے لیے یوٹیلیٹی خالص فنکشنز لکھوں گا۔ اسٹیٹ کو کسی بھی دوسری ریڈکس ایپلی کیشن کی طرح اعمال اور ریڈوسرز کا استعمال کرتے ہوئے ہیر پھیر کیا جاتا ہے۔

میں جہاں تک ممکن ہو کلاسیکی وراثت کے استعمال سے گریز کرتا ہوں۔ جب اور اگر میں ایسا کرتا ہوں تو میں [ان قواعد] پر قائم رہتا ہوں۔

ہوسٹ آبجیکٹس اور نیٹو آبجیکٹس میں کیا فرق ہے؟

نیٹو آبجیکٹس وہ آبجیکٹس ہیں جو ECMAScript کی وضاحت کے ذریعے جاوا اسکرپٹ زبان کا حصہ ہیں، جیسے 'String'، 'Math'، 'RegExp'، 'Object'، 'Function' وغیرہ۔

ہوسٹ آبجیکٹس رن ٹائم ماحول (براؤزر یا نوڈ) کے ذریعہ فراہم کیے جاتے ہیں، جیسے 'window'، 'XMLHTTPRequest' وغیرہ۔

فرق: 'function Person(){}'، 'var person = Person()'، اور 'var person = new Person()'؟

یہ سوال کافی مبہم ہے۔ اس کے ارادے کا میرا بہترین اندازہ یہ ہے کہ یہ جاوا اسکرپٹ میں کنسٹرکٹرز کے بارے میں پوچھ رہا ہے۔ تکنیکی طور پر، 'function Person(){}' صرف ایک عام فنکشن کا اعلان ہے۔ روایت یہ ہے کہ ان فنکشنز کے لیے PascalCase استعمال کیا جائے جن کا مقصد کنسٹرکٹرز کے طور پر استعمال ہونا ہے۔

'var person = Person()' 'Person' کو ایک فنکشن کے طور پر بلاتا ہے، کنسٹرکٹر کے طور پر نہیں۔ اس طرح بلانا ایک عام غلطی ہے اگر فنکشن کا مقصد کنسٹرکٹر کے طور پر استعمال ہونا ہو۔ عام طور پر، کنسٹرکٹر کچھ بھی واپس نہیں کرتا، لہذا کنسٹرکٹر کو ایک عام فنکشن کی طرح بلانے سے 'undefined' واپس آئے گا اور وہ اس متغیر کو تفویض کیا جائے گا جس کا مقصد مثال ہے۔

'var person = new Person()' 'new' آپریٹر کا استعمال کرتے ہوئے 'Person' آبجیکٹ کی ایک مثال بناتا ہے، جو 'Person.prototype' سے وراثت میں ملتا ہے۔ ایک متبادل 'Object.create' کا استعمال کرنا ہوگا، جیسے: 'Object.create(Person.prototype)'۔

function Person(name) { this.name = name; } var person = Person('John'); console.log(person); // undefined console.log(person.name); // Uncaught TypeError: Cannot read property 'name' of undefined var person = new Person('John'); console.log(person); // Person { name: 'John' } console.log(person.name); // 'john'

'.call' اور '.apply' میں کیا فرق ہے؟

دونوں '.call' اور '.apply' فنکشنز کو بلانے کے لیے استعمال ہوتے ہیں اور پہلا پیرامیٹر فنکشن کے اندر 'this' کی قدر کے طور پر استعمال ہوگا۔ تاہم، '.call' اگلے دلائل کے طور پر کوما سے الگ دلائل لیتا ہے جبکہ '.apply' اگلے دلیل کے طور پر دلائل کی ایک صف لیتا ہے۔ اسے یاد رکھنے کا ایک آسان طریقہ 'call' کے لیے C اور کوما سے الگ اور 'apply' کے لیے A اور دلائل کی ایک صف ہے۔

function add(a, b) { return a + b; } console.log(add.call(null, 1, 2)); // 3 console.log(add.apply(null, [1, 2])); // 3

Explain 'Function.prototype.bind'.

[MDN] سے لفظ بہ لفظ لیا گیا:

'bind()' میتھڈ ایک نیا فنکشن بناتا ہے جو، جب بلایا جاتا ہے، تو اس کا 'this' کی ورڈ فراہم کردہ قدر پر سیٹ ہوتا ہے، نئے فنکشن کو بلائے جانے پر فراہم کردہ کسی بھی دلائل سے پہلے دلائل کی ایک دی گئی ترتیب کے ساتھ۔

میرے تجربے میں، یہ کلاسز کے طریقوں میں 'this' کی قدر کو پابند کرنے کے لیے سب سے زیادہ مفید ہے جسے آپ دوسرے فنکشنز میں پاس کرنا چاہتے ہیں۔ یہ ری ایکٹ اجزاء میں اکثر کیا جاتا ہے۔

آپ 'document.write()' کب استعمال کریں گے؟

'document.write()' 'document.open()' کے ذریعہ کھولی گئی دستاویز سٹریم میں ٹیکسٹ کی ایک سٹرنگ لکھتا ہے۔ جب صفحہ لوڈ ہونے کے بعد 'document.write()' کو چلایا جاتا ہے، تو یہ 'document.open' کو کال کرے گا جو پوری دستاویز ('<head>' اور '<body>' کو ہٹا دیتا ہے!) کو صاف کر دیتا ہے اور مواد کو دی گئی پیرامیٹر ویلیو سے بدل دیتا ہے۔ لہذا اسے عام طور پر خطرناک اور غلط استعمال کا شکار سمجھا جاتا ہے۔

آن لائن کچھ جوابات ہیں جو وضاحت کرتے ہیں کہ 'document.write()' اینالیٹکس کوڈ میں استعمال ہو رہا ہے یا [جب آپ ایسے اسٹائل شامل کرنا چاہتے ہیں جو صرف جاوا اسکرپٹ فعال ہونے پر کام کریں]۔ اسے HTML5 بوائلر پلیٹ میں بھی استعمال کیا جا رہا ہے تاکہ [اسکرپٹس کو متوازی طور پر لوڈ کیا جا سکے اور عملدرآمد کی ترتیب کو برقرار رکھا جا سکے]! تاہم، مجھے شبہ ہے کہ یہ وجوہات پرانی ہو سکتی ہیں اور آج کل، انہیں 'document.write()' استعمال کیے بغیر حاصل کیا جا سکتا ہے۔ اگر میں اس بارے میں غلط ہوں تو براہ کرم مجھے درست کریں۔

فیچر ڈیٹیکشن، فیچر انفرنس، اور UA سٹرنگ استعمال کرنے میں کیا فرق ہے؟

فیچر ڈیٹیکشن

فیچر ڈیٹیکشن میں یہ معلوم کرنا شامل ہے کہ آیا ایک براؤزر کوڈ کے ایک مخصوص بلاک کو سپورٹ کرتا ہے، اور اس بات پر منحصر ہے کہ آیا یہ کرتا ہے (یا نہیں کرتا)، مختلف کوڈ چلانا، تاکہ براؤزر ہمیشہ ایک فعال تجربہ فراہم کر سکے بجائے اس کے کہ کچھ براؤزرز میں کریش/غلطی ہو۔ مثال کے طور پر:

if ('geolocation' in navigator) { // navigator.geolocation استعمال کر سکتے ہیں } else { // فیچر کی کمی کو سنبھالیں }

[Modernizr] فیچر ڈیٹیکشن کو سنبھالنے کے لیے ایک بہترین لائبریری ہے۔

فیچر انفرنس

فیچر انفرنس فیچر ڈیٹیکشن کی طرح ایک فیچر کو چیک کرتا ہے، لیکن ایک اور فنکشن کا استعمال کرتا ہے کیونکہ یہ فرض کرتا ہے کہ یہ بھی موجود ہوگا، مثلاً:

if (document.getElementsByTagName) { element = document.getElementById(id); }

یہ واقعی تجویز نہیں کیا جاتا ہے۔ فیچر ڈیٹیکشن زیادہ فول پروف ہے۔

UA سٹرنگ

یہ ایک براؤزر سے رپورٹ کی جانے والی سٹرنگ ہے جو نیٹ ورک پروٹوکول کے ہم منصبوں کو درخواست کرنے والے سافٹ ویئر یوزر ایجنٹ کی ایپلیکیشن کی قسم، آپریٹنگ سسٹم، سافٹ ویئر وینڈر یا سافٹ ویئر ورژن کی شناخت کرنے کی اجازت دیتی ہے۔ اس تک 'navigator.userAgent' کے ذریعے رسائی حاصل کی جا سکتی ہے۔ تاہم، سٹرنگ کو پارس کرنا مشکل ہے اور اسے دھوکہ دیا جا سکتا ہے۔ مثال کے طور پر، کروم کروم اور سفاری دونوں کے طور پر رپورٹ کرتا ہے۔ لہذا سفاری کا پتہ لگانے کے لیے آپ کو سفاری سٹرنگ اور کروم سٹرنگ کی عدم موجودگی کو چیک کرنا ہوگا۔ اس طریقہ سے بچیں۔

Ajax کی جتنی تفصیل سے ہو سکے وضاحت کریں۔

Ajax (asynchronous JavaScript and XML) ویب ڈویلپمنٹ تکنیکوں کا ایک مجموعہ ہے جو کلائنٹ سائیڈ پر بہت سی ویب ٹیکنالوجیز کا استعمال کرتا ہے تاکہ غیر متوازی ویب ایپلی کیشنز تیار کی جا سکیں۔ Ajax کے ساتھ، ویب ایپلی کیشنز سرور سے ڈیٹا کو غیر متوازی طور پر (پس منظر میں) بھیج سکتی ہیں اور حاصل کر سکتی ہیں بغیر موجودہ صفحہ کے ڈسپلے اور رویے میں مداخلت کیے۔ ڈیٹا انٹرچینج پرت کو پریزنٹیشن پرت سے الگ کرکے، Ajax ویب صفحات، اور توسیع کے ذریعے ویب ایپلی کیشنز کو، پورے صفحے کو دوبارہ لوڈ کرنے کی ضرورت کے بغیر مواد کو متحرک طور پر تبدیل کرنے کی اجازت دیتا ہے۔ عملی طور پر، جدید نفاذات عام طور پر XML کے بجائے JSON کا استعمال کرتے ہیں، کیونکہ JSON کے جاوا اسکرپٹ کے لیے مقامی ہونے کے فوائد ہیں۔

'XMLHttpRequest' API کو غیر متوازی مواصلات کے لیے اکثر استعمال کیا جاتا ہے یا آج کل، 'fetch()' API کو۔

Ajax استعمال کرنے کے فوائد اور نقصانات کیا ہیں؟

فوائد

  • بہتر انٹرایکٹیویٹی۔ سرور سے نیا مواد پورے صفحے کو دوبارہ لوڈ کرنے کی ضرورت کے بغیر متحرک طور پر تبدیل کیا جا سکتا ہے۔
  • سرور سے کنکشنز کم کریں کیونکہ اسکرپٹس اور اسٹائل شیٹس کو صرف ایک بار درخواست کرنے کی ضرورت ہوتی ہے۔
  • صفحے پر حالت کو برقرار رکھا جا سکتا ہے۔ جاوا اسکرپٹ متغیرات اور DOM حالت برقرار رہے گی کیونکہ مرکزی کنٹینر کا صفحہ دوبارہ لوڈ نہیں کیا گیا تھا۔
  • بنیادی طور پر ایک SPA کے زیادہ تر فوائد۔

نقصانات

  • متحرک ویب صفحات کو بک مارک کرنا مشکل ہوتا ہے۔
  • اگر براؤزر میں جاوا اسکرپٹ کو غیر فعال کر دیا گیا ہو تو کام نہیں کرتا۔
  • کچھ ویب کرالر جاوا اسکرپٹ کو نہیں چلاتے اور جاوا اسکرپٹ کے ذریعہ لوڈ کیے گئے مواد کو نہیں دیکھیں گے۔
  • Ajax کا استعمال کرتے ہوئے ڈیٹا حاصل کرنے والے ویب صفحات کو ممکنہ طور پر حاصل کردہ ریموٹ ڈیٹا کو کلائنٹ سائیڈ ٹیمپلیٹس کے ساتھ ملانا پڑے گا تاکہ DOM کو اپ ڈیٹ کیا جا سکے۔ ایسا ہونے کے لیے، جاوا اسکرپٹ کو براؤزر پر پارس اور چلانا پڑے گا، اور کم درجے کے موبائل آلات کو اس میں مشکلات کا سامنا کرنا پڑ سکتا ہے۔
  • بنیادی طور پر ایک SPA کے زیادہ تر نقصانات۔

وضاحت کریں کہ JSONP کیسے کام کرتا ہے (اور یہ دراصل Ajax نہیں ہے)۔

JSONP (JSON with Padding) ایک ایسا طریقہ ہے جو عام طور پر ویب براؤزرز میں کراس ڈومین پالیسیوں کو بائی پاس کرنے کے لیے استعمال ہوتا ہے کیونکہ موجودہ صفحہ سے کراس اوریجن ڈومین پر Ajax درخواستوں کی اجازت نہیں ہے۔

JSONP ایک '<script>' ٹیگ کے ذریعے کراس اوریجن ڈومین پر ایک درخواست کرکے کام کرتا ہے اور عام طور پر ایک 'callback' کوئری پیرامیٹر کے ساتھ، مثال کے طور پر: 'https://example.com?callback=printData'۔ سرور پھر ڈیٹا کو 'printData' نامی فنکشن کے اندر لپیٹ دے گا اور اسے کلائنٹ کو واپس کر دے گا۔

<script> function printData(data) { console.log(`My name is ${data.name}!`); } </script> <script src="[https://example.com?callback=printData](https://example.com?callback=printData)"></script>
printData({ name: 'Yang Shun' });

کلائنٹ کے پاس اپنی عالمی گنجائش میں 'printData' فنکشن ہونا ضروری ہے اور فنکشن کو کلائنٹ کے ذریعہ چلایا جائے گا جب کراس اوریجن ڈومین سے جواب موصول ہوگا۔

JSONP غیر محفوظ ہو سکتا ہے اور اس کے کچھ سیکیورٹی مضمرات ہیں۔ چونکہ JSONP دراصل جاوا اسکرپٹ ہے، یہ ہر وہ کام کر سکتا ہے جو جاوا اسکرپٹ کر سکتا ہے، لہذا آپ کو JSONP ڈیٹا کے فراہم کنندہ پر بھروسہ کرنے کی ضرورت ہے۔

آج کل، [CORS] تجویز کردہ طریقہ ہے اور JSONP کو ایک ہیک کے طور پر دیکھا جاتا ہے۔

کیا آپ نے کبھی جاوا اسکرپٹ ٹیمپلیٹنگ استعمال کی ہے؟ اگر ہاں، تو آپ نے کون سی لائبریریاں استعمال کی ہیں؟

جی ہاں۔ ہینڈل بارز، انڈرسکور، لوڈیش، AngularJS، اور JSX۔ مجھے AngularJS میں ٹیمپلیٹنگ ناپسند تھی کیونکہ یہ ڈائریکٹیوز میں سٹرنگز کا بہت زیادہ استعمال کرتا تھا اور ٹائپوز پکڑے نہیں جاتے تھے۔ JSX میرا نیا پسندیدہ ہے کیونکہ یہ جاوا اسکرپٹ کے قریب ہے اور سیکھنے کے لیے بمشکل کوئی syntax ہے۔ آج کل، آپ ES2015 ٹیمپلیٹ سٹرنگ لٹریلز کو بھی تیسری پارٹی کے کوڈ پر انحصار کیے بغیر ٹیمپلیٹس بنانے کے لیے ایک تیز طریقہ کے طور پر استعمال کر سکتے ہیں۔

const template = `<div>My name is: ${name}</div>`;

تاہم، اوپر کے طریقے میں ممکنہ XSS سے آگاہ رہیں کیونکہ ٹیمپلیٹنگ لائبریریوں کے برعکس، مواد کو آپ کے لیے escape نہیں کیا جاتا۔

'hoisting' کی وضاحت کریں۔

ہوئسٹنگ ایک اصطلاح ہے جو آپ کے کوڈ میں متغیر کے اعلانات کے رویے کی وضاحت کے لیے استعمال ہوتی ہے۔ 'var' کی ورڈ کے ساتھ اعلان کردہ یا شروع کیے گئے متغیرات کا اعلان ان کے ماڈیول/فنکشن کی سطح کے دائرہ کار کے اوپری حصے میں 'منتقل' کر دیا جائے گا، جسے ہم hoisting کہتے ہیں۔ تاہم، صرف اعلان کو ہی hoiste کیا جاتا ہے، تفویض (اگر کوئی ہے) وہیں رہے گی۔

یاد رہے کہ اعلان واقعی منتقل نہیں ہوتا ہے - جاوا اسکرپٹ انجن کمپائلیشن کے دوران اعلانات کو پارس کرتا ہے اور اعلانات اور ان کے دائرہ کار سے آگاہ ہو جاتا ہے۔ اس رویے کو اسکوپ کے اوپر اعلانات کو hoiste کے طور پر تصور کرکے سمجھنا آسان ہے۔ آئیے چند مثالوں کے ساتھ وضاحت کریں۔

console.log(foo); // undefined var foo = 1; console.log(foo); // 1

فنکشن کے اعلانات میں باڈی کو hoiste کیا جاتا ہے جبکہ فنکشن ایکسپریشنز (متغیر کے اعلانات کی شکل میں لکھے گئے) میں صرف متغیر کے اعلان کو hoiste کیا جاتا ہے۔

// فنکشن ڈیکلریشن console.log(foo); // [Function: foo] foo(); // 'FOOOOO' function foo() { console.log('FOOOOO'); } console.log(foo); // [Function: foo] // فنکشن ایکسپریشن console.log(bar); // undefined bar(); // Uncaught TypeError: bar is not a function var bar = function () { console.log('BARRRR'); }; console.log(bar); // [Function: bar]

'let' اور 'const' کے ذریعے اعلان کردہ متغیرات بھی hoiste کیے جاتے ہیں۔ تاہم، 'var' اور 'function' کے برعکس، انہیں شروع نہیں کیا جاتا ہے اور اعلان سے پہلے ان تک رسائی حاصل کرنے کے نتیجے میں 'ReferenceError' استثناء ہوگا۔ متغیر بلاک کے آغاز سے لے کر اعلان پر کارروائی ہونے تک 'ٹیمپیرل ڈیڈ زون' میں رہتا ہے۔

x; // undefined y; // Reference error: y is not defined var x = 'local'; let y = 'local';

ایونٹ بلبلنگ کی وضاحت کریں۔

جب کسی DOM عنصر پر کوئی ایونٹ متحرک ہوتا ہے، تو وہ ایونٹ کو سنبھالنے کی کوشش کرے گا اگر کوئی لسنر منسلک ہو، پھر ایونٹ اپنے پیرنٹ تک بلبلہ اوپر آ جاتا ہے اور وہی چیز ہوتی ہے۔ یہ بلبلہ عنصر کے آبائی عناصر تک 'document' تک ہوتا ہے۔ ایونٹ بلبلنگ ایونٹ ڈیلیگیشن کے پیچھے کا طریقہ کار ہے۔

ایک 'attribute' اور ایک 'property' میں کیا فرق ہے؟

خصوصیات HTML مارک اپ پر تعریف کی جاتی ہیں لیکن خصوصیات DOM پر تعریف کی جاتی ہیں۔ فرق کو واضح کرنے کے لیے، تصور کریں کہ ہمارے HTML میں یہ ٹیکسٹ فیلڈ ہے: '<input type="text" value="Hello">

const input = document.querySelector('input'); console.log(input.getAttribute('value')); // Hello console.log(input.value); // Hello

لیکن جب آپ ٹیکسٹ فیلڈ کی قدر کو 'World!' شامل کرکے تبدیل کرتے ہیں تو یہ بن جاتا ہے:

console.log(input.getAttribute('value')); // Hello console.log(input.value); // Hello World!

بلٹ ان جاوا اسکرپٹ آبجیکٹس کو بڑھانا کیوں اچھا خیال نہیں ہے؟

ایک بلٹ ان/نیٹو جاوا اسکرپٹ آبجیکٹ کو بڑھانے کا مطلب اس کے 'پروٹوٹائپ' میں خصوصیات/فنکشنز شامل کرنا ہے۔ اگرچہ یہ پہلے اچھا خیال لگ سکتا ہے، لیکن عملی طور پر یہ خطرناک ہے۔ تصور کریں کہ آپ کا کوڈ چند لائبریریاں استعمال کرتا ہے جو دونوں 'Array.prototype' کو ایک ہی 'contains' میتھڈ شامل کرکے بڑھاتے ہیں، تو نفاذ ایک دوسرے کو اوور رائیٹ کر دیں گے اور اگر ان دونوں طریقوں کا رویہ ایک جیسا نہیں ہے تو آپ کا کوڈ ٹوٹ جائے گا۔

ایک نیٹو آبجیکٹ کو بڑھانے کا واحد وقت یہ ہے کہ جب آپ ایک پولی فل بنانا چاہتے ہیں، بنیادی طور پر ایک میتھڈ کے لیے اپنی اپنی نفاذ فراہم کرتے ہیں جو جاوا اسکرپٹ کی تفصیلات کا حصہ ہے لیکن پرانے براؤزر ہونے کی وجہ سے صارف کے براؤزر میں موجود نہیں ہو سکتا۔

document 'load' ایونٹ اور document 'DOMContentLoaded' ایونٹ میں کیا فرق ہے؟

'DOMContentLoaded' ایونٹ اس وقت فائر ہوتا ہے جب ابتدائی HTML دستاویز مکمل طور پر لوڈ اور پارس ہو جاتی ہے، اسٹائل شیٹس، تصاویر اور سب فریمز کے لوڈ ہونے کا انتظار کیے بغیر۔

'window' کا 'load' ایونٹ صرف DOM اور تمام منحصر وسائل اور اثاثوں کے لوڈ ہونے کے بعد فائر ہوتا ہے۔

'==' اور '===' میں کیا فرق ہے؟

'==' خلاصہ مساوات آپریٹر ہے جبکہ '===' سخت مساوات آپریٹر ہے۔ '==' آپریٹر کسی بھی ضروری قسم کی تبدیلیوں کے بعد مساوات کا موازنہ کرے گا۔ '===' آپریٹر قسم کی تبدیلی نہیں کرے گا، لہذا اگر دو اقدار ایک ہی قسم کی نہیں ہیں تو '===' صرف 'false' واپس کرے گا۔ '==' استعمال کرتے وقت، عجیب و غریب چیزیں ہو سکتی ہیں، جیسے:

1 == '1'; // true 1 == [1]; // true 1 == true; // true 0 == ''; // true 0 == '0'; // true 0 == false; // true

میری نصیحت ہے کہ '==' آپریٹر کبھی استعمال نہ کریں، سوائے اس کے کہ 'null' یا 'undefined' کے خلاف موازنہ کرتے وقت سہولت کے لیے، جہاں 'a == null' 'true' واپس کرے گا اگر 'a' 'null' یا 'undefined' ہے۔

var a = null; console.log(a == null); // true console.log(a == undefined); // true

جاوا اسکرپٹ کے حوالے سے سیم اوریجن پالیسی کی وضاحت کریں۔

سیم اوریجن پالیسی جاوا اسکرپٹ کو ڈومین کی حدود سے درخواستیں کرنے سے روکتی ہے۔ ایک اوریجن کو URI اسکیم، ہوسٹ نام، اور پورٹ نمبر کے امتزاج کے طور پر تعریف کیا جاتا ہے۔ یہ پالیسی ایک صفحے پر ایک بدنیتی پر مبنی اسکرپٹ کو اس صفحے کے Document Object Model کے ذریعے دوسرے ویب صفحے پر حساس ڈیٹا تک رسائی حاصل کرنے سے روکتی ہے۔

اسے کام کریں:

duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]
function duplicate(arr) { return arr.concat(arr); } duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]

یا ES6 کے ساتھ:

const duplicate = (arr) => [...arr, ...arr]; duplicate([1, 2, 3, 4, 5]); // [1,2,3,4,5,1,2,3,4,5]

اسے Ternary expression کیوں کہا جاتا ہے، لفظ 'Ternary' کس چیز کی نشاندہی کرتا ہے؟

'Ternary' تین کی نشاندہی کرتا ہے، اور ایک Ternary expression تین آپرینٹس کو قبول کرتا ہے، ٹیسٹ کنڈیشن، 'then' ایکسپریشن اور 'else' ایکسپریشن۔ Ternary expressions جاوا اسکرپٹ کے لیے مخصوص نہیں ہیں اور مجھے نہیں معلوم کہ یہ اس فہرست میں کیوں ہے۔

'use strict';' کیا ہے؟ اسے استعمال کرنے کے کیا فوائد اور نقصانات ہیں؟

'use strict' ایک بیان ہے جو سخت موڈ کو پورے اسکرپٹس یا انفرادی فنکشنز کو فعال کرنے کے لیے استعمال ہوتا ہے۔ سخت موڈ جاوا اسکرپٹ کے ایک محدود قسم میں شامل ہونے کا ایک طریقہ ہے۔

فوائد:

  • حادثاتی طور پر عالمی متغیرات بنانا ناممکن بنا دیتا ہے۔
  • ایسی تفویضات جو بصورت دیگر خاموشی سے ناکام ہو جاتی ہیں، استثناء کو پھینک دیتی ہیں۔
  • ایسی کوششوں کو جو ناقابل حذف خصوصیات کو حذف کرنے کی کوشش کرتی ہیں، استثناء کو پھینک دیتی ہیں (جہاں پہلے کوشش کا کوئی اثر نہیں ہوتا تھا)۔
  • تقاضا کرتا ہے کہ فنکشن پیرامیٹر کے نام منفرد ہوں۔
  • عالمی سیاق و سباق میں 'this' undefined ہے۔
  • یہ کچھ عام کوڈنگ کی غلطیوں کو پکڑتا ہے، استثناء پھینک کر۔
  • یہ ایسی خصوصیات کو غیر فعال کرتا ہے جو الجھن کا باعث یا ناقص سوچ سمجھی جاتی ہیں۔

نقصانات:

  • بہت سی گمشدہ خصوصیات جن کے کچھ ڈویلپرز عادی ہو سکتے ہیں۔
  • 'function.caller' اور 'function.arguments' تک مزید رسائی نہیں۔
  • مختلف سخت موڈز میں لکھے گئے اسکرپٹس کیConcatenation مسائل کا سبب بن سکتی ہے۔

مجموعی طور پر، مجھے لگتا ہے کہ فوائد نقصانات سے زیادہ ہیں، اور مجھے کبھی بھی ایسی خصوصیات پر انحصار نہیں کرنا پڑا جو سخت موڈ بلاک کرتا ہے۔ میں سخت موڈ استعمال کرنے کی سفارش کروں گا۔

ایک 'for' لوپ بنائیں جو '100' تک دہرائے جبکہ '3' کے گناہوں پر **'fizz'**، '5' کے گناہوں پر **'buzz'** اور '3' اور '5' کے گناہوں پر **'fizzbuzz'** آؤٹ پٹ کرے۔

[Paul Irish] کے FizzBuzz کے اس ورژن کو دیکھیں۔

for (let i = 1; i <= 100; i++) { let f = i % 3 == 0, b = i % 5 == 0; console.log(f ? (b ? 'FizzBuzz' : 'Fizz') : b ? 'Buzz' : i); }

میں آپ کو مشورہ نہیں دوں گا کہ آپ انٹرویوز کے دوران اوپر کا کوڈ لکھیں۔ بس لمبا لیکن واضح طریقہ پر قائم رہیں۔ FizzBuzz کے مزید عجیب و غریب ورژنز کے لیے، نیچے حوالہ لنک دیکھیں۔

عام طور پر، ویب سائٹ کے عالمی دائرہ کار کو ویسے ہی چھوڑ دینا اور اسے کبھی ہاتھ نہ لگانا ایک اچھا خیال کیوں ہے؟

ہر اسکرپٹ کو عالمی دائرہ کار تک رسائی حاصل ہوتی ہے، اور اگر ہر کوئی اپنے متغیرات کی تعریف کرنے کے لیے عالمی نام کی جگہ کا استعمال کرتا ہے، تو تصادم کا امکان زیادہ ہوتا ہے۔ اپنے متغیرات کو مقامی نام کی جگہ کے اندر encapsule کرنے کے لیے ماڈیول پیٹرن (IIFEs) کا استعمال کریں۔

'load' ایونٹ جیسی چیز آپ کیوں استعمال کریں گے؟ کیا اس ایونٹ کے نقصانات ہیں؟ کیا آپ کوئی متبادل جانتے ہیں، اور آپ انہیں کیوں استعمال کریں گے؟

'load' ایونٹ دستاویز لوڈنگ کے عمل کے اختتام پر فائر ہوتا ہے۔ اس وقت، دستاویز میں موجود تمام آبجیکٹس DOM میں ہوتے ہیں، اور تمام تصاویر، اسکرپٹس، لنکس اور سب فریمز لوڈ ہونا ختم ہو چکے ہوتے ہیں۔

DOM ایونٹ 'DOMContentLoaded' صفحے کے لیے DOM کی تعمیر کے بعد فائر ہوگا، لیکن دیگر وسائل کے لوڈ ہونے کا انتظار نہیں کرتا۔ یہ مخصوص حالات میں ترجیح دی جاتی ہے جب آپ کو شروع کرنے سے پہلے پورا صفحہ لوڈ کرنے کی ضرورت نہیں ہوتی۔

ایک سنگل پیج ایپ کیا ہے اور اسے SEO دوستانہ کیسے بنایا جائے اس کی وضاحت کریں

ذیل میں زبردست [Grab Front End Guide] سے لیا گیا ہے، جو اتفاق سے، میں نے خود لکھا ہے!

آج کل ویب ڈویلپرز اپنی بنائی ہوئی مصنوعات کو ویب سائٹ کے بجائے ویب ایپس کہتے ہیں۔ اگرچہ دونوں اصطلاحات کے درمیان کوئی سخت فرق نہیں ہے، ویب ایپس بہت زیادہ انٹرایکٹو اور ڈائنامک ہوتی ہیں، جو صارف کو کارروائیاں کرنے اور ان کے عمل کا جواب حاصل کرنے کی اجازت دیتی ہیں۔ روایتی طور پر، براؤزر سرور سے HTML وصول کرتا ہے اور اسے رینڈر کرتا ہے۔ جب صارف کسی دوسرے URL پر نیویگیٹ کرتا ہے، تو پورے صفحے کی ریفریش کی ضرورت ہوتی ہے اور سرور نئے صفحے پر تازہ HTML بھیجتا ہے۔ اسے سرور سائیڈ رینڈرنگ کہتے ہیں۔

تاہم، جدید SPA میں، کلائنٹ سائیڈ رینڈرنگ کا استعمال کیا جاتا ہے۔ براؤزر سرور سے ابتدائی صفحہ لوڈ کرتا ہے، اس کے ساتھ پورے ایپ کے لیے مطلوبہ اسکرپٹس (فریم ورکس، لائبریریز، ایپ کوڈ) اور اسٹائل شیٹس بھی۔ جب صارف دوسرے صفحات پر نیویگیٹ کرتا ہے، تو صفحے کی ریفریش شروع نہیں ہوتی۔ صفحے کا URL [HTML5 History API] کے ذریعے اپ ڈیٹ ہوتا ہے۔ نئے صفحے کے لیے مطلوبہ نیا ڈیٹا، عام طور پر JSON فارمیٹ میں، براؤزر کے ذریعے سرور کو [AJAX] درخواستوں کے ذریعے بازیافت کیا جاتا ہے۔ پھر SPA جاوا اسکرپٹ کے ذریعے صفحے کو ڈیٹا کے ساتھ متحرک طور پر اپ ڈیٹ کرتا ہے، جسے اس نے ابتدائی صفحہ لوڈ میں پہلے ہی ڈاؤن لوڈ کر لیا ہے۔ یہ ماڈل اسی طرح ہے جیسے مقامی موبائل ایپس کام کرتی ہیں۔

فوائد:

  • ایپ زیادہ ریسپانسیو محسوس ہوتی ہے اور صارف پورے صفحے کی ریفریش کی وجہ سے صفحات کی نیویگیشن کے درمیان چمک نہیں دیکھتے۔
  • سرور کو کم HTTP درخواستیں کی جاتی ہیں، کیونکہ ہر صفحہ لوڈ کے لیے ایک ہی اثاثوں کو دوبارہ ڈاؤن لوڈ کرنے کی ضرورت نہیں ہوتی۔
  • کلائنٹ اور سرور کے درمیان خدشات کی واضح علیحدگی؛ آپ سرور کوڈ میں ترمیم کیے بغیر مختلف پلیٹ فارمز (مثلاً موبائل، چیٹ بوٹس، سمارٹ گھڑیاں) کے لیے آسانی سے نئے کلائنٹس بنا سکتے ہیں۔ آپ کلائنٹ اور سرور پر ٹیکنالوجی اسٹیک کو بھی آزادانہ طور پر تبدیل کر سکتے ہیں، جب تک کہ API معاہدہ نہ ٹوٹے۔

نقصانات:

  • متعدد صفحات کے لیے مطلوبہ فریم ورک، ایپ کوڈ، اور اثاثوں کو لوڈ کرنے کی وجہ سے ابتدائی صفحہ لوڈ بھاری ہوتا ہے۔
  • آپ کے سرور پر ایک اضافی قدم اٹھانے کی ضرورت ہے جو اسے تمام درخواستوں کو ایک ہی انٹری پوائنٹ پر روٹ کرنے اور کلائنٹ سائیڈ روٹنگ کو وہاں سے سنبھالنے کی اجازت دینے کے لیے تشکیل دینا ہے۔
  • SPAs مواد کو رینڈر کرنے کے لیے جاوا اسکرپٹ پر منحصر ہیں، لیکن تمام سرچ انجن کرولنگ کے دوران جاوا اسکرپٹ کو نہیں چلاتے، اور وہ آپ کے صفحے پر خالی مواد دیکھ سکتے ہیں۔ یہ نادانستہ طور پر آپ کے ایپ کی سرچ انجن آپٹیمائزیشن (SEO) کو نقصان پہنچاتا ہے۔ تاہم، زیادہ تر وقت، جب آپ ایپس بنا رہے ہوتے ہیں، SEO سب سے اہم عنصر نہیں ہوتا، کیونکہ تمام مواد کو سرچ انجنوں کے ذریعے انڈیکس کرنے کی ضرورت نہیں ہوتی۔ اس پر قابو پانے کے لیے، آپ یا تو اپنے ایپ کو سرور سائیڈ رینڈر کر سکتے ہیں یا [Prerender] جیسی خدمات استعمال کر سکتے ہیں تاکہ 'اپنے جاوا اسکرپٹ کو براؤزر میں رینڈر کریں، جامد HTML کو محفوظ کریں، اور اسے کرالرز کو واپس کریں۔'

پراومسز اور/یا ان کے پولی فلز کے ساتھ آپ کا تجربہ کس حد تک ہے؟

اس کا عملی علم رکھتا ہوں۔ پراومس ایک آبجیکٹ ہے جو مستقبل میں کسی وقت ایک واحد ویلیو پیدا کر سکتا ہے: یا تو ایک حل شدہ ویلیو یا ایک وجہ کہ یہ حل نہیں ہوا (مثلاً، نیٹ ورک کی خرابی واقع ہوئی)۔ ایک پراومس 3 ممکنہ حالتوں میں سے ایک میں ہو سکتا ہے: مکمل شدہ، مسترد شدہ، یا زیر التوا۔ پراومس کے صارفین مکمل شدہ ویلیو یا مسترد ہونے کی وجہ کو سنبھالنے کے لیے کال بیکس منسلک کر سکتے ہیں۔

کچھ عام پولی فلز $.deferred، Q اور Bluebird ہیں لیکن ان میں سے سبھی تفصیلات کے مطابق نہیں ہیں۔ ES2015 باکس سے باہر پراومسز کو سپورٹ کرتا ہے اور آج کل عام طور پر پولی فلز کی ضرورت نہیں ہوتی ہے۔

کال بیکس کے بجائے پراومسز استعمال کرنے کے کیا فوائد اور نقصانات ہیں؟

فوائد

  • کال بیک ہیل سے بچیں جو ناقابل پڑھ ہو سکتی ہے۔
  • .then() کے ساتھ پڑھنے کے قابل ترتیب غیر ہم آہنگ کوڈ لکھنا آسان بناتا ہے۔
  • Promise.all() کے ساتھ متوازی غیر ہم آہنگ کوڈ لکھنا آسان بناتا ہے۔
  • پراومسز کے ساتھ، یہ منظرنامے جو صرف کال بیکس کوڈنگ میں موجود ہیں، نہیں ہوں گے:
    • کال بیک کو بہت جلد کال کرنا
    • کال بیک کو بہت دیر سے (یا کبھی نہیں) کال کرنا
    • کال بیک کو بہت کم یا بہت زیادہ بار کال کرنا
    • کسی بھی ضروری ماحول/پیرامیٹرز کو پاس نہ کرنا
    • کسی بھی غلطیوں/استثناء کو نگل جانا جو ہو سکتا ہے

نقصانات

  • قدرے زیادہ پیچیدہ کوڈ (بحث مباحثہ)۔
  • پرانے براؤزرز میں جہاں ES2015 کی حمایت نہیں کی جاتی ہے، آپ کو اسے استعمال کرنے کے لیے ایک پولی فل لوڈ کرنے کی ضرورت ہے۔

جاوا اسکرپٹ میں ایسے زبان میں کوڈ لکھنے کے کیا فوائد/نقصانات ہیں جو جاوا اسکرپٹ میں مرتب ہوتی ہے؟

جاوا اسکرپٹ میں مرتب ہونے والی کچھ زبانوں کی مثالوں میں CoffeeScript، Elm، ClojureScript، PureScript، اور TypeScript شامل ہیں۔

فوائد:

  • جاوا اسکرپٹ میں کچھ دیرینہ مسائل کو ٹھیک کرتا ہے اور جاوا اسکرپٹ کے اینٹی پیٹرن کو حوصلہ شکنی کرتا ہے۔
  • جاوا اسکرپٹ کے اوپر کچھ سنتیکٹک شوگر فراہم کرکے آپ کو مختصر کوڈ لکھنے کے قابل بناتا ہے، جو میرے خیال میں ES5 میں کمی ہے، لیکن ES2015 زبردست ہے۔
  • بڑے پراجیکٹس کے لیے جو وقت کے ساتھ برقرار رکھنے کی ضرورت ہے، جامد اقسام زبردست ہیں (TypeScript کے معاملے میں)۔

نقصانات:

  • ایک بلڈ/کمپائل عمل کی ضرورت ہوتی ہے کیونکہ براؤزر صرف جاوا اسکرپٹ چلاتے ہیں اور آپ کے کوڈ کو براؤزر کو فراہم کرنے سے پہلے جاوا اسکرپٹ میں مرتب کرنے کی ضرورت ہوگی۔
  • اگر آپ کے سورس میپس آپ کے پری-کمپائلڈ سورس سے اچھی طرح سے میپ نہیں ہوتے ہیں تو ڈیبگنگ ایک مشکل کام ہو سکتا ہے۔
  • زیادہ تر ڈویلپرز ان زبانوں سے واقف نہیں ہیں اور انہیں یہ سیکھنے کی ضرورت ہوگی۔ اگر آپ اپنے پراجیکٹس کے لیے اسے استعمال کرتے ہیں تو آپ کی ٹیم کے لیے ایک اضافی لاگت شامل ہے۔
  • چھوٹی کمیونٹی (زبان پر منحصر ہے)، جس کا مطلب ہے کہ وسائل، ٹیوٹوریلز، لائبریریز، اور ٹولنگ تلاش کرنا مشکل ہوگا۔
  • IDE/ایڈیٹر کی حمایت میں کمی ہو سکتی ہے۔
  • یہ زبانیں ہمیشہ تازہ ترین جاوا اسکرپٹ معیار سے پیچھے رہیں گی۔
  • ڈویلپرز کو اس بات سے واقف ہونا چاہیے کہ ان کا کوڈ کس چیز میں مرتب ہو رہا ہے - کیونکہ وہی دراصل چل رہا ہوگا، اور وہی آخر میں اہمیت رکھتا ہے۔

عملی طور پر، ES2015 نے جاوا اسکرپٹ کو بہت بہتر بنایا ہے اور اسے لکھنا بہت اچھا بنا دیا ہے۔ مجھے آج کل CoffeeScript کی واقعی ضرورت نظر نہیں آتی۔

جاوا اسکرپٹ کوڈ کو ڈیبگ کرنے کے لیے آپ کون سے ٹولز اور تکنیک استعمال کرتے ہیں؟

  • React اور Redux
    • [React Devtools]
    • [Redux Devtools]
  • Vue
    • [Vue Devtools]
  • جاوا اسکرپٹ
    • [Chrome Devtools]
    • debugger بیان
    • اچھا پرانا console.log ڈیبگنگ

آبجیکٹ پراپرٹیز اور ارے آئٹمز کو دہرانے کے لیے آپ کون سی زبان کی تعمیرات استعمال کرتے ہیں؟

آبجیکٹس کے لیے:

  • for-in لوپس - for (var property in obj) { console.log(property); }۔ تاہم، یہ اس کی وراثتی پراپرٹیز کو بھی دہرائے گا، اور آپ اسے استعمال کرنے سے پہلے ایک obj.hasOwnProperty(property) چیک شامل کریں گے۔
  • Object.keys() - Object.keys(obj).forEach(function (property) { ... })۔ Object.keys() ایک جامد طریقہ ہے جو آپ اسے پاس کرنے والے آبجیکٹ کی تمام قابل شمار پراپرٹیز کی فہرست دے گا۔
  • Object.getOwnPropertyNames() - Object.getOwnPropertyNames(obj).forEach(function (property) { ... })۔ Object.getOwnPropertyNames() ایک جامد طریقہ ہے جو آپ اسے پاس کرنے والے آبجیکٹ کی تمام قابل شمار اور غیر قابل شمار پراپرٹیز کی فہرست دے گا۔

ایریز کے لیے:

  • for لوپس - for (var i = 0; i < arr.length; i++)۔ یہاں عام خامی یہ ہے کہ var فنکشن کے دائرہ کار میں ہے نہ کہ بلاک کے دائرہ کار میں اور زیادہ تر وقت آپ بلاک اسکوپڈ اٹریٹر ویری ایبل چاہتے ہوں گے۔ ES2015 نے let متعارف کرایا ہے جس کا بلاک اسکوپ ہے اور اس کی بجائے اسے استعمال کرنے کی سفارش کی جاتی ہے۔ تو یہ بن جاتا ہے: for (let i = 0; i < arr.length; i++)۔
  • forEach - arr.forEach(function (el, index) { ... })۔ یہ تعمیر بعض اوقات زیادہ آسان ہو سکتی ہے کیونکہ اگر آپ کو صرف ارے عناصر کی ضرورت ہو تو آپ کو index استعمال کرنے کی ضرورت نہیں ہے۔ every اور some کے طریقے بھی ہیں جو آپ کو ابتدائی طور پر دہرانے کو ختم کرنے کی اجازت دیں گے۔
  • for-of لوپس - for (let elem of arr) { ... }۔ ES6 نے ایک نیا لوپ، for-of لوپ متعارف کرایا ہے، جو آپ کو قابل تکرار پروٹوکول کے مطابق آبجیکٹس پر لوپ کرنے کی اجازت دیتا ہے جیسے String، Array، Map، Set، وغیرہ۔ یہ for لوپ اور forEach() طریقہ کے فوائد کو یکجا کرتا ہے۔ for لوپ کا فائدہ یہ ہے کہ آپ اس سے بریک کر سکتے ہیں، اور forEach() کا فائدہ یہ ہے کہ یہ for لوپ سے زیادہ مختصر ہے کیونکہ آپ کو کاؤنٹر ویری ایبل کی ضرورت نہیں ہے۔ for-of لوپ کے ساتھ، آپ کو لوپ سے بریک کرنے کی صلاحیت اور ایک زیادہ مختصر نحو دونوں ملتے ہیں۔

زیادہ تر وقت، میں .forEach طریقہ کو ترجیح دوں گا، لیکن یہ واقعی اس بات پر منحصر ہے کہ آپ کیا کرنے کی کوشش کر رہے ہیں۔ ES6 سے پہلے، جب ہمیں break کا استعمال کرتے ہوئے لوپ کو وقت سے پہلے ختم کرنے کی ضرورت ہوتی تھی تو ہم for لوپس کا استعمال کرتے تھے۔ لیکن اب ES6 کے ساتھ، ہم for-of لوپس کے ساتھ ایسا کر سکتے ہیں۔ جب مجھے اور بھی زیادہ لچک کی ضرورت ہوتی ہے، جیسے کہ فی لوپ میں اٹریٹر کو ایک سے زیادہ بار بڑھانا تو میں for لوپس کا استعمال کروں گا۔

اس کے علاوہ، for-of لوپ کا استعمال کرتے ہوئے، اگر آپ کو ہر ارے عنصر کے انڈیکس اور ویلیو دونوں تک رسائی کی ضرورت ہے، تو آپ ES6 Array entries() طریقہ اور ڈسٹرکچرنگ کے ساتھ ایسا کر سکتے ہیں:

const arr = ['a', 'b', 'c']; for (let [index, elem] of arr.entries()) { console.log(index, ': ', elem); }

mutable اور immutable آبجیکٹ کے درمیان فرق واضح کریں۔

Immutability فنکشنل پروگرامنگ میں ایک بنیادی اصول ہے، اور آبجیکٹ اورینٹڈ پروگراموں کو بھی بہت کچھ پیش کرنا ہے۔ ایک mutable آبجیکٹ ایک ایسا آبجیکٹ ہے جس کی حالت اسے بنانے کے بعد تبدیل کی جا سکتی ہے۔ ایک immutable آبجیکٹ ایک ایسا آبجیکٹ ہے جس کی حالت اسے بنانے کے بعد تبدیل نہیں کی جا سکتی۔

جاوا اسکرپٹ میں ایک immutable آبجیکٹ کی مثال کیا ہے؟

جاوا اسکرپٹ میں، کچھ بلٹ ان اقسام (نمبرز، سٹرنگز) immutable ہیں، لیکن کسٹم آبجیکٹ عام طور پر mutable ہوتے ہیں۔

کچھ بلٹ ان immutable جاوا اسکرپٹ آبجیکٹ Math، Date ہیں۔

یہاں سادہ جاوا اسکرپٹ آبجیکٹس پر immutability شامل کرنے/نقلی کرنے کے چند طریقے ہیں۔

آبجیکٹ مستقل خصوصیات

writable: false اور configurable: false کو ملا کر، آپ بنیادی طور پر ایک مستقل (تبدیل نہیں کیا جا سکتا، دوبارہ تعریف یا حذف نہیں کیا جا سکتا) ایک آبجیکٹ پراپرٹی کے طور پر بنا سکتے ہیں، جیسے:

let myObject = {}; Object.defineProperty(myObject, 'number', { value: 42, writable: false, configurable: false, }); console.log(myObject.number); // 42 myObject.number = 43; console.log(myObject.number); // 42

توسیع سے روکیں

اگر آپ کسی آبجیکٹ کو نئی پراپرٹیز شامل کرنے سے روکنا چاہتے ہیں، لیکن آبجیکٹ کی باقی پراپرٹیز کو اکیلا چھوڑ دیں، تو Object.preventExtensions(...) کو کال کریں:

var myObject = { a: 2, }; Object.preventExtensions(myObject); myObject.b = 3; myObject.b; // undefined

نان-سٹرکٹ موڈ میں، b کی تخلیق خاموشی سے ناکام ہو جاتی ہے۔ سٹرکٹ موڈ میں، یہ ایک TypeError پھینکتا ہے۔

سیل

Object.seal() ایک 'سیل شدہ' آبجیکٹ بناتا ہے، جس کا مطلب ہے کہ یہ ایک موجودہ آبجیکٹ لیتا ہے اور بنیادی طور پر اس پر Object.preventExtensions() کو کال کرتا ہے، بلکہ اس کی تمام موجودہ پراپرٹیز کو بھی configurable: false کے طور پر نشان زد کرتا ہے۔

لہذا، نہ صرف آپ مزید پراپرٹیز شامل نہیں کر سکتے، بلکہ آپ کسی بھی موجودہ پراپرٹیز کو دوبارہ کنفیگر یا حذف بھی نہیں کر سکتے (اگرچہ آپ اب بھی ان کی قدروں کو تبدیل کر سکتے ہیں)۔

فریز

Object.freeze() ایک منجمد آبجیکٹ بناتا ہے، جس کا مطلب ہے کہ یہ ایک موجودہ آبجیکٹ لیتا ہے اور بنیادی طور پر اس پر Object.seal() کو کال کرتا ہے، بلکہ یہ تمام 'ڈیٹا ایکسیسر' پراپرٹیز کو بھی writable:false کے طور پر نشان زد کرتا ہے، تاکہ ان کی قدریں تبدیل نہ کی جا سکیں۔

یہ نقطہ نظر immutability کی اعلیٰ ترین سطح ہے جو آپ خود آبجیکٹ کے لیے حاصل کر سکتے ہیں، کیونکہ یہ آبجیکٹ یا اس کی کسی بھی براہ راست پراپرٹیز میں کسی بھی تبدیلی کو روکتا ہے (اگرچہ، جیسا کہ اوپر ذکر کیا گیا ہے، کسی بھی حوالہ شدہ دیگر آبجیکٹ کے مواد پر کوئی اثر نہیں پڑتا)۔

var immutable = Object.freeze({});

آبجیکٹ کو فریز کرنے سے نئی پراپرٹیز کو آبجیکٹ میں شامل کرنے کی اجازت نہیں ملتی اور موجودہ پراپرٹیز کو ہٹانے یا تبدیل کرنے سے روکتا ہے۔ Object.freeze() آبجیکٹ کی شمار، کنفیگر، رائٹ اور پروٹوٹائپ کو محفوظ رکھتا ہے۔ یہ پاس شدہ آبجیکٹ کو واپس کرتا ہے اور منجمد کاپی نہیں بناتا ہے۔

immutability کے کیا فوائد اور نقصانات ہیں؟

فوائد

  • تبدیلی کا پتہ لگانا آسان - آبجیکٹ کی مساوات کو حوالہ جاتی مساوات کے ذریعے پرفارمنٹ اور آسان طریقے سے طے کیا جا سکتا ہے۔ یہ React اور Redux میں آبجیکٹ کے اختلافات کا موازنہ کرنے کے لیے مفید ہے۔
  • immutable آبجیکٹس والے پروگراموں کے بارے میں سوچنا کم پیچیدہ ہوتا ہے، کیونکہ آپ کو یہ فکر کرنے کی ضرورت نہیں ہوتی کہ وقت کے ساتھ آبجیکٹ کیسے ترقی کر سکتا ہے۔
  • فنکشنز سے immutable آبجیکٹس کو واپس کرتے یا پاس کرتے وقت ڈیفینسیو کاپیوں کی مزید ضرورت نہیں ہوتی، کیونکہ immutable آبجیکٹ کے ذریعے ترمیم کا کوئی امکان نہیں ہے۔
  • حوالوں کے ذریعے آسان شیئرنگ - ایک آبجیکٹ کی ایک کاپی اتنی ہی اچھی ہے جتنی کوئی اور، لہذا آپ آبجیکٹس کو کیش کر سکتے ہیں یا ایک ہی آبجیکٹ کو کئی بار دوبارہ استعمال کر سکتے ہیں۔
  • تھریڈ سیف - immutable آبجیکٹس کو کثیر تھریڈ والے ماحول میں تھریڈز کے درمیان محفوظ طریقے سے استعمال کیا جا سکتا ہے کیونکہ ان کے دیگر بیک وقت چلنے والے تھریڈز میں ترمیم ہونے کا کوئی خطرہ نہیں ہوتا ہے۔
  • ImmutableJS جیسی لائبریریوں کا استعمال کرتے ہوئے، آبجیکٹ کو structural sharing کا استعمال کرتے ہوئے تبدیل کیا جاتا ہے اور اسی طرح کی ساخت کے ساتھ متعدد آبجیکٹ رکھنے کے لیے کم میموری کی ضرورت ہوتی ہے۔

نقصانات

  • immutable ڈیٹا سٹرکچرز اور اس کے آپریشنز کی نادانستہ عملدرآمد کے نتیجے میں انتہائی خراب کارکردگی ہو سکتی ہے کیونکہ ہر بار نئے آبجیکٹ بنائے جاتے ہیں۔ موثر immutable ڈیٹا سٹرکچرز اور آپریشنز کے لیے لائبریریاں استعمال کرنے کی سفارش کی جاتی ہے جو structural sharing کا فائدہ اٹھاتے ہیں۔
  • موجودہ آبجیکٹ کو تبدیل کرنے کے بجائے بہت سے چھوٹے آبجیکٹ کی تخصیص (اور تخصیص سے دستبرداری) کارکردگی پر اثر انداز ہو سکتی ہے۔ ایلوکیٹر یا گاربیج کلیکٹر کی پیچیدگی عام طور پر ہیپ پر موجود آبجیکٹس کی تعداد پر منحصر ہوتی ہے۔
  • سائیکلک ڈیٹا سٹرکچرز جیسے گراف بنانا مشکل ہوتا ہے۔ اگر آپ کے پاس دو آبجیکٹ ہیں جنہیں انیشلائزیشن کے بعد تبدیل نہیں کیا جا سکتا، تو آپ انہیں ایک دوسرے کی طرف کیسے اشارہ کر سکتے ہیں؟

آپ اپنے کوڈ میں immutability کیسے حاصل کر سکتے ہیں؟

متبادل یہ ہے کہ const اعلانات کو تخلیق کے لیے اوپر ذکر کردہ تکنیکوں کے ساتھ مل کر استعمال کیا جائے۔ آبجیکٹس کو 'تبدیل' کرنے کے لیے، اصل آبجیکٹ کو تبدیل کرنے کے بجائے نئے آبجیکٹ بنانے کے لیے اسپریڈ آپریٹر، Object.assign، Array.concat() وغیرہ کا استعمال کریں۔

مثالیں:

// Array Example const arr = [1, 2, 3]; const newArr = [...arr, 4]; // [1, 2, 3, 4] // Object Example const human = Object.freeze({ race: 'human' }); const john = { ...human, name: 'John' }; // {race: "human", name: "John"} const alienJohn = { ...john, race: 'alien' }; // {race: "alien", name: "John"}

synchronous اور asynchronous فنکشنز کے درمیان فرق واضح کریں۔

Synchronous فنکشنز بلاکنگ ہوتے ہیں جبکہ asynchronous فنکشنز نہیں ہوتے۔ synchronous فنکشنز میں، اگلے بیان کے چلنے سے پہلے بیان مکمل ہوتے ہیں۔ اس صورت میں، پروگرام کا اندازہ بیانات کی ترتیب میں بالکل اسی طرح کیا جاتا ہے اور اگر کوئی بیان بہت زیادہ وقت لے تو پروگرام کا عمل روک دیا جاتا ہے۔

Asynchronous فنکشنز عام طور پر ایک کال بیک کو پیرامیٹر کے طور پر قبول کرتے ہیں اور غیر ہم آہنگ فنکشن کو کال کرنے کے فوراً بعد اگلی لائن پر عمل جاری رہتا ہے۔ کال بیک صرف اس وقت کال کیا جاتا ہے جب غیر ہم آہنگ آپریشن مکمل ہو جائے اور کال اسٹیک خالی ہو۔ بھاری کارروائیاں جیسے ویب سرور سے ڈیٹا لوڈ کرنا یا ڈیٹا بیس سے استفسار کرنا غیر ہم آہنگ طریقے سے کیا جانا چاہیے تاکہ مین تھریڈ دیگر کارروائیوں کو انجام دیتا رہے بجائے اس کے کہ اس طویل کارروائی کے مکمل ہونے تک (براؤزر کے معاملے میں، UI منجمد ہو جائے گا)۔

ایونٹ لوپ کیا ہے؟ کال اسٹیک اور ٹاسک کیو کے درمیان کیا فرق ہے؟

ایونٹ لوپ ایک سنگل تھریڈڈ لوپ ہے جو کال اسٹیک کی نگرانی کرتا ہے اور چیک کرتا ہے کہ ٹاسک کیو میں کوئی کام کرنا باقی ہے یا نہیں۔ اگر کال اسٹیک خالی ہے اور ٹاسک کیو میں کال بیک فنکشنز ہیں، تو ایک فنکشن کو ڈی کیو کیا جاتا ہے اور اسے چلانے کے لیے کال اسٹیک پر دھکیل دیا جاتا ہے۔

اگر آپ نے ابھی تک ایونٹ لوپ پر فلپ رابرٹ کی گفتگو نہیں دیکھی ہے، تو آپ کو دیکھنی چاہیے۔ یہ جاوا اسکرپٹ پر سب سے زیادہ دیکھی جانے والی ویڈیوز میں سے ایک ہے۔

`function foo() {}` اور `var foo = function() {}` کے درمیان `foo` کے استعمال میں کیا فرق ہے؟

پہلا ایک فنکشن ڈیکلریشن ہے جبکہ دوسرا ایک فنکشن ایکسپریشن ہے۔ اہم فرق یہ ہے کہ فنکشن ڈیکلریشن کی باڈی ہوسٹ کی جاتی ہے لیکن فنکشن ایکسپریشن کی باڈی نہیں (ان کا ویری ایبلز کی طرح ہی ہوسٹنگ رویہ ہوتا ہے)۔ ہوسٹنگ کے بارے میں مزید وضاحت کے لیے، اوپر والا سوال on hoisting دیکھیں۔ اگر آپ کسی فنکشن ایکسپریشن کو اس کے ڈیفائن ہونے سے پہلے کال کرنے کی کوشش کرتے ہیں، تو آپ کو Uncaught TypeError: XXX is not a function کی خرابی ملے گی۔

فنکشن ڈیکلریشن

foo(); // 'FOOOOO' function foo() { console.log('FOOOOO'); }

فنکشن ایکسپریشن

foo(); // Uncaught TypeError: foo is not a function var foo = function () { console.log('FOOOOO'); };

`let`, `var` یا `const` کا استعمال کرتے ہوئے بنائے گئے متغیرات کے درمیان کیا فرق ہے؟

var کلید لفظ کا استعمال کرتے ہوئے اعلان کردہ متغیرات اس فنکشن کے دائرہ کار میں ہوتے ہیں جس میں وہ بنائے جاتے ہیں، یا اگر کسی فنکشن کے باہر بنائے جاتے ہیں، تو عالمی آبجیکٹ تک۔ let اور const بلاک اسکوپڈ ہوتے ہیں، یعنی وہ صرف قریب ترین curly braces (فنکشن، if-else بلاک، یا for-loop) کے اندر قابل رسائی ہوتے ہیں۔

function foo() { // تمام متغیرات فنکشنز کے اندر قابل رسائی ہوتے ہیں۔ var bar = 'bar'; let baz = 'baz'; const qux = 'qux'; console.log(bar); // bar console.log(baz); // baz console.log(qux); // qux } console.log(bar); // ReferenceError: bar is not defined console.log(baz); // ReferenceError: baz is not defined console.log(qux); // ReferenceError: qux is not defined
if (true) { var bar = 'bar'; let baz = 'baz'; const qux = 'qux'; } // var کا استعمال کرتے ہوئے اعلان کردہ متغیرات فنکشن کے دائرہ کار میں کہیں بھی قابل رسائی ہوتے ہیں۔ console.log(bar); // bar // let اور const کا استعمال کرتے ہوئے تعریف کردہ متغیرات ان بلاکس کے باہر قابل رسائی نہیں ہوتے جن میں وہ تعریف کیے گئے تھے۔ console.log(baz); // ReferenceError: baz is not defined console.log(qux); // ReferenceError: qux is not defined

var متغیرات کو ہوسٹ کرنے کی اجازت دیتا ہے، یعنی انہیں کوڈ میں ان کے اعلان سے پہلے حوالہ دیا جا سکتا ہے۔ let اور const اس کی اجازت نہیں دیں گے، بلکہ ایک غلطی پھینکیں گے۔

console.log(foo); // undefined var foo = 'foo'; console.log(baz); // ReferenceError: can't access lexical declaration 'baz' before initialization let baz = 'baz'; console.log(bar); // ReferenceError: can't access lexical declaration 'bar' before initialization const bar = 'bar';

var کے ساتھ ایک متغیر کو دوبارہ اعلان کرنے سے غلطی نہیں ہوگی، لیکن let اور const غلطی دیں گے۔

var foo = 'foo'; var foo = 'bar'; console.log(foo); // "bar" let baz = 'baz'; let baz = 'qux'; // Uncaught SyntaxError: Identifier 'baz' has already been declared

let اور const اس میں مختلف ہیں کہ let متغیر کی قدر کو دوبارہ تفویض کرنے کی اجازت دیتا ہے جبکہ const نہیں دیتا۔

// یہ ٹھیک ہے۔ let foo = 'foo'; foo = 'bar'; // یہ ایک استثناء کا سبب بنتا ہے۔ const baz = 'baz'; baz = 'qux';

ES6 کلاس اور ES5 فنکشن کنسٹرکٹرز کے درمیان کیا فرق ہے؟

آئیے پہلے ہر ایک کی مثال دیکھیں:

// ES5 فنکشن کنسٹرکٹر function Person(name) { this.name = name; } // ES6 کلاس class Person { constructor(name) { this.name = name; } }

سادہ کنسٹرکٹرز کے لیے، وہ کافی ملتے جلتے نظر آتے ہیں۔

کنسٹرکٹر میں اہم فرق وراثت کا استعمال کرتے وقت آتا ہے۔ اگر ہم ایک Student کلاس بنانا چاہتے ہیں جو Person کو سب کلاس کرے اور ایک studentId فیلڈ شامل کرے، تو ہمیں مندرجہ بالا کے علاوہ یہ کرنا ہوگا:

// ES5 فنکشن کنسٹرکٹر function Student(name, studentId) { // سپر کلاس کے کنسٹرکٹر کو کال کریں تاکہ سپر کلاس سے ماخوذ اراکین کو انیشیلائز کیا جا سکے۔ Person.call(this, name); // سب کلاس کے اپنے اراکین کو انیشیلائز کریں۔ this.studentId = studentId; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; // ES6 کلاس class Student extends Person { constructor(name, studentId) { super(name); this.studentId = studentId; } }

ES5 میں وراثت کا استعمال کرنا بہت زیادہ پیچیدہ ہے اور ES6 ورژن سمجھنے اور یاد رکھنے میں آسان ہے۔

کیا آپ نئے ایرو => فنکشن سنٹیکس کے استعمال کا ایک کیس پیش کر سکتے ہیں؟ یہ نیا سنٹیکس دوسرے فنکشنز سے کیسے مختلف ہے؟

ایرو فنکشنز کا ایک واضح فائدہ یہ ہے کہ فنکشنز بنانے کے لیے درکار سنٹیکس کو آسان بنانا، function کلید لفظ کی ضرورت کے بغیر۔ ایرو فنکشنز کے اندر this بھی منسلک اسکوپ سے منسلک ہوتا ہے جو باقاعدہ فنکشنز کے مقابلے میں مختلف ہے جہاں this اسے کال کرنے والے آبجیکٹ سے طے ہوتا ہے۔ لغوی طور پر اسکوپڈ this کال بیکس کو کال کرتے وقت خاص طور پر React اجزاء میں مفید ہے۔

کنسٹرکٹر میں کسی میتھڈ کے لیے ایرو سنٹیکس استعمال کرنے کا کیا فائدہ ہے؟

کنسٹرکٹر کے اندر ایک میتھڈ کے طور پر ایرو فنکشن استعمال کرنے کا بنیادی فائدہ یہ ہے کہ فنکشن کی تخلیق کے وقت this کی ویلیو سیٹ ہو جاتی ہے اور اس کے بعد تبدیل نہیں ہو سکتی۔ لہذا، جب کنسٹرکٹر کو ایک نیا آبجیکٹ بنانے کے لیے استعمال کیا جاتا ہے، تو this ہمیشہ اس آبجیکٹ کا حوالہ دے گا۔ مثال کے طور پر، فرض کریں کہ ہمارے پاس ایک Person کنسٹرکٹر ہے جو پہلے نام کو آرگومنٹ کے طور پر لیتا ہے اور اس نام کو console.log کرنے کے لیے دو میتھڈز ہیں، ایک باقاعدہ فنکشن کے طور پر اور دوسرا ایرو فنکشن کے طور پر:

const Person = function (firstName) { this.firstName = firstName; this.sayName1 = function () { console.log(this.firstName); }; this.sayName2 = () => { console.log(this.firstName); }; }; const john = new Person('John'); const dave = new Person('Dave'); john.sayName1(); // John john.sayName2(); // John // باقاعدہ فنکشن کی 'this' ویلیو کو تبدیل کیا جا سکتا ہے، لیکن ایرو فنکشن کی نہیں john.sayName1.call(dave); // Dave (کیونکہ 'this' اب ڈیو آبجیکٹ ہے) john.sayName2.call(dave); // John john.sayName1.apply(dave); // Dave (کیونکہ 'this' اب ڈیو آبجیکٹ ہے) john.sayName2.apply(dave); // John john.sayName1.bind(dave)(); // Dave (کیونکہ 'this' اب ڈیو آبجیکٹ ہے) john.sayName2.bind(dave)(); // John var sayNameFromWindow1 = john.sayName1; sayNameFromWindow1(); // undefined (کیونکہ 'this' اب ونڈو آبجیکٹ ہے) var sayNameFromWindow2 = john.sayName2; sayNameFromWindow2(); // John

یہاں اہم بات یہ ہے کہ ایک نارمل فنکشن کے لیے this کو تبدیل کیا جا سکتا ہے، لیکن ایرو فنکشن کے لیے سیاق و سباق ہمیشہ ایک جیسا رہتا ہے۔ لہذا اگر آپ اپنے ایرو فنکشن کو اپنے ایپلیکیشن کے مختلف حصوں میں پاس کر رہے ہیں، تو آپ کو سیاق و سباق کی تبدیلی کے بارے میں فکر کرنے کی ضرورت نہیں ہوگی۔

یہ React کلاس اجزاء میں خاص طور پر مددگار ثابت ہو سکتا ہے۔ اگر آپ کسی کلاس میتھڈ کو کسی چیز کے لیے جیسے کہ ایک کلک ہینڈلر کو نارمل فنکشن کا استعمال کرتے ہوئے بیان کرتے ہیں، اور پھر آپ اس کلک ہینڈلر کو چائلڈ کمپوننٹ میں ایک پروپ کے طور پر پاس کرتے ہیں، تو آپ کو پیرنٹ کمپوننٹ کے کنسٹرکٹر میں this کو بھی بائنڈ کرنے کی ضرورت ہوگی۔ اگر آپ اس کے بجائے ایرو فنکشن استعمال کرتے ہیں، تو this کو بائنڈ کرنے کی کوئی ضرورت نہیں ہے، کیونکہ میتھڈ خود بخود اپنی this ویلیو اپنے منسلک لغوی سیاق و سباق سے حاصل کر لے گا۔

اعلی ترتیب والے فنکشن کی تعریف کیا ہے؟

ایک اعلی ترتیب والا فنکشن وہ فنکشن ہے جو ایک یا زیادہ فنکشنز کو دلائل کے طور پر لیتا ہے، جسے وہ کچھ ڈیٹا پر کام کرنے کے لیے استعمال کرتا ہے، اور/یا نتیجے کے طور پر ایک فنکشن واپس کرتا ہے۔ اعلی ترتیب والے فنکشنز کا مقصد کچھ ایسی کارروائی کو تجرید کرنا ہے جو بار بار انجام دی جاتی ہے۔ اس کی کلاسک مثال map ہے، جو ایک ارے اور ایک فنکشن کو دلائل کے طور پر لیتا ہے۔ map پھر اس فنکشن کو ارے میں ہر آئٹم کو تبدیل کرنے کے لیے استعمال کرتا ہے، تبدیل شدہ ڈیٹا کے ساتھ ایک نئی ارے واپس کرتا ہے۔ جاوا اسکرپٹ میں دیگر مقبول مثالیں forEach، filter، اور reduce ہیں۔ ایک اعلی ترتیب والے فنکشن کو صرف ارے کو ہی ہیر پھیر کرنے کی ضرورت نہیں ہے کیونکہ دوسرے فنکشن سے فنکشن واپس کرنے کے بہت سے استعمال کے معاملات ہیں۔ Function.prototype.bind جاوا اسکرپٹ میں ایسی ہی ایک مثال ہے۔

میپ

فرض کریں کہ ہمارے پاس ناموں کی ایک ارے ہے جسے ہمیں ہر سٹرنگ کو اپر کیس میں تبدیل کرنے کی ضرورت ہے۔

const names = ['irish', 'daisy', 'anna'];

ضروری طریقہ اس طرح ہوگا:

const transformNamesToUppercase = function (names) { const results = []; for (let i = 0; i < names.length; i++) { results.push(names[i].toUpperCase()); } return results; }; transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']

.map(transformerFn) کا استعمال کوڈ کو مختصر اور زیادہ اعلانیہ بناتا ہے۔

const transformNamesToUppercase = function (names) { return names.map((name) => name.toUpperCase()); }; transformNamesToUppercase(names); // ['IRISH', 'DAISY', 'ANNA']

کیا آپ آبجیکٹ یا ارے کو ڈسٹرکچر کرنے کی مثال دے سکتے ہیں؟

ڈسٹرکچرنگ ES6 میں دستیاب ایک اظہار ہے جو آبجیکٹس یا ایریز کی قدروں کو نکالنے اور انہیں الگ الگ متغیرات میں رکھنے کا ایک مختصر اور آسان طریقہ فراہم کرتا ہے۔

ایرے ڈسٹرکچرنگ

// متغیر تفویض۔ const foo = ['one', 'two', 'three']; const [one, two, three] = foo; console.log(one); // "one" console.log(two); // "two" console.log(three); // "three"
// متغیرات کو تبدیل کرنا let a = 1; let b = 3; [a, b] = [b, a]; console.log(a); // 3 console.log(b); // 1

آبجیکٹ ڈسٹرکچرنگ

// متغیر تفویض۔ const o = { p: 42, q: true }; const { p, q } = o; console.log(p); // 42 console.log(q); // true

ES6 ٹیمپلیٹ لٹرلز سٹرنگز بنانے میں بہت لچک پیش کرتے ہیں، کیا آپ ایک مثال دے سکتے ہیں؟

ٹیمپلیٹ لٹرلز سٹرنگ انٹرپولیشن کو آسان بنانے، یا کسی سٹرنگ میں متغیرات کو شامل کرنے میں مدد کرتے ہیں۔ ES2015 سے پہلے، ایسا کچھ کرنا عام تھا:

var person = { name: 'Tyler', age: 28 }; console.log( 'Hi, my name is ' + person.name + ' and I am ' + person.age + ' years old!', ); // 'Hi, my name is Tyler and I am 28 years old!'

ٹیمپلیٹ لٹرلز کے ساتھ، اب آپ اسی آؤٹ پٹ کو اس طرح بنا سکتے ہیں:

const person = { name: 'Tyler', age: 28 }; console.log(`Hi, my name is ${person.name} and I am ${person.age} years old!`); // 'Hi, my name is Tyler and I am 28 years old!'

یاد رکھیں کہ آپ بیکٹکس استعمال کرتے ہیں، کوٹس نہیں، یہ ظاہر کرنے کے لیے کہ آپ ٹیمپلیٹ لٹرل استعمال کر رہے ہیں اور آپ ${} پلیس ہولڈرز کے اندر اظہار داخل کر سکتے ہیں۔

ایک دوسرا مددگار استعمال کا معاملہ ملٹی لائن سٹرنگز بنانے میں ہے۔ ES2015 سے پہلے، آپ ایک ملٹی لائن سٹرنگ اس طرح بنا سکتے تھے:

console.log('This is line one.\nThis is line two.'); // This is line one. // This is line two.

یا اگر آپ اسے اپنے کوڈ میں متعدد لائنوں میں توڑنا چاہتے تھے تاکہ آپ کو ایک لمبی سٹرنگ پڑھنے کے لیے اپنے ٹیکسٹ ایڈیٹر میں دائیں طرف اسکرول نہ کرنا پڑے، تو آپ اسے اس طرح بھی لکھ سکتے تھے:

console.log('This is line one.\n' + 'This is line two.'); // This is line one. // This is line two.

تاہم، ٹیمپلیٹ لٹرلز جو بھی خالی جگہ آپ ان میں شامل کرتے ہیں اسے محفوظ رکھتے ہیں۔ مثال کے طور پر، اسی ملٹی لائن آؤٹ پٹ کو بنانے کے لیے جو ہم نے اوپر بنایا تھا، آپ آسانی سے کر سکتے ہیں:

console.log(`This is line one. This is line two.`); // This is line one. // This is line two.

ٹیمپلیٹ لٹرلز کا ایک اور استعمال کا معاملہ سادہ متغیر انٹرپولیشن کے لیے ٹیمپلیٹنگ لائبریریوں کے متبادل کے طور پر استعمال کرنا ہوگا:

const person = { name: 'Tyler', age: 28 }; document.body.innerHTML = ` <div> <p>Name: ${person.name}</p> <p>Age: ${person.age}</p> </div> `;

نوٹ کریں کہ آپ کا کوڈ .innerHTML کا استعمال کرتے ہوئے XSS کے لیے حساس ہو سکتا ہے۔ اگر ڈیٹا صارف سے آیا ہے تو اسے ظاہر کرنے سے پہلے اسے صاف کریں!

کیا آپ کرری فنکشن کی ایک مثال دے سکتے ہیں اور یہ سنٹیکس کیوں فائدہ پیش کرتا ہے؟

Currying ایک ایسا نمونہ ہے جہاں ایک سے زیادہ پیرامیٹرز والا فنکشن متعدد فنکشنز میں توڑا جاتا ہے جو، جب سیریز میں کال کیے جاتے ہیں، تو تمام مطلوبہ پیرامیٹرز کو ایک وقت میں جمع کریں گے۔ یہ تکنیک فنکشنل انداز میں لکھے گئے کوڈ کو پڑھنے اور ترتیب دینے میں آسان بنانے کے لیے مفید ہو سکتی ہے۔ یہ نوٹ کرنا ضروری ہے کہ کسی فنکشن کو کرری کرنے کے لیے، اسے پہلے ایک فنکشن کے طور پر شروع کرنا پڑتا ہے، پھر اسے فنکشنز کی ایک ترتیب میں توڑا جاتا ہے جو ہر ایک پیرامیٹر کو قبول کرتا ہے۔

function curry(fn) { if (fn.length === 0) { return fn; } function _curried(depth, args) { return function (newArgument) { if (depth - 1 === 0) { return fn(...args, newArgument); } return _curried(depth - 1, [...args, newArgument]); }; } return _curried(fn.length, []); } function add(a, b) { return a + b; } var curriedAdd = curry(add); var addFive = curriedAdd(5); var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]

اسپریڈ سنٹیکس استعمال کرنے کے کیا فوائد ہیں اور یہ ریسٹ سنٹیکس سے کیسے مختلف ہے؟

ES6 کا اسپریڈ سنٹیکس فنکشنل پیراڈائم میں کوڈنگ کرتے وقت بہت مفید ہے کیونکہ ہم Object.create، slice، یا کسی لائبریری فنکشن کا سہارا لیے بغیر آسانی سے ایریز یا آبجیکٹ کی کاپیاں بنا سکتے ہیں۔ یہ زبان کی خصوصیت اکثر Redux اور RxJS پراجیکٹس میں استعمال ہوتی ہے۔

function putDookieInAnyArray(arr) { return [...arr, 'dookie']; } const result = putDookieInAnyArray(['I', 'really', "don't", 'like']); // ["I", "really", "don't", "like", "dookie"] const person = { name: 'Todd', age: 29, }; const copyOfTodd = { ...person };

ES6 کا ریسٹ سنٹیکس فنکشن کو پاس کیے جانے والے دلائل کی ایک صوابدیدی تعداد کو شامل کرنے کے لیے ایک مختصر طریقہ پیش کرتا ہے۔ یہ اسپریڈ سنٹیکس کا ایک الٹا ہے، جو ڈیٹا لیتا ہے اور اسے ایک ارے میں بھرتا ہے بجائے اس کے کہ ڈیٹا کی ایک ارے کو کھولے، اور یہ فنکشن دلائل کے ساتھ ساتھ ارے اور آبجیکٹ ڈسٹرکچرنگ اسائنمنٹس میں بھی کام کرتا ہے۔

function addFiveToABunchOfNumbers(...numbers) { return numbers.map((x) => x + 5); } const result = addFiveToABunchOfNumbers(4, 5, 6, 7, 8, 9, 10); // [9, 10, 11, 12, 13, 14, 15] const [a, b, ...rest] = [1, 2, 3, 4]; // a: 1, b: 2, rest: [3, 4] const { e, f, ...others } = { e: 1, f: 2, g: 3, h: 4, }; // e: 1, f: 2, others: { g: 3, h: 4 }

آپ فائلوں کے درمیان کوڈ کیسے شیئر کر سکتے ہیں؟

یہ جاوا اسکرپٹ ماحول پر منحصر ہے۔

کلائنٹ (براؤزر ماحول) پر، جب تک متغیرات/فنکشنز عالمی دائرہ کار (window) میں اعلان کیے جاتے ہیں، تمام اسکرپٹس ان کا حوالہ دے سکتے ہیں۔ متبادل طور پر، زیادہ ماڈیولر نقطہ نظر کے لیے RequireJS کے ذریعے Asynchronous Module Definition (AMD) کو اپنائیں۔

سرور (Node.js) پر، عام طریقہ CommonJS کا استعمال کرنا رہا ہے۔ ہر فائل کو ایک ماڈیول کے طور پر سمجھا جاتا ہے اور یہ module.exports آبجیکٹ سے منسلک کرکے متغیرات اور فنکشنز کو ایکسپورٹ کر سکتا ہے۔

ES2015 ایک ماڈیول سنٹیکس کی وضاحت کرتا ہے جس کا مقصد AMD اور CommonJS دونوں کو تبدیل کرنا ہے۔ اسے بالآخر براؤزر اور نوڈ دونوں ماحول میں سپورٹ کیا جائے گا۔

آپ جامد کلاس ممبرز کیوں بنانا چاہیں گے؟

جامد کلاس ممبرز (پراپرٹیز/میتھڈز) کلاس کے کسی مخصوص مثال سے منسلک نہیں ہوتے اور اس کی قدر وہی رہتی ہے قطع نظر اس کے کہ کون سی مثال اس کا حوالہ دے رہی ہے۔ جامد پراپرٹیز عام طور پر کنفیگریشن متغیرات ہوتے ہیں اور جامد میتھڈز عام طور پر خالص یوٹیلیٹی فنکشنز ہوتے ہیں جو مثال کی حالت پر منحصر نہیں ہوتے۔