یہ سیکشن جاوا اسکرپٹ کے بارے میں تھوڑا سا پس منظر فراہم کرتا ہے تاکہ آپ کو یہ سمجھنے میں مدد ملے کہ یہ اس طرح کیوں ہے۔
ECMAScript جاوا اسکرپٹ کا سرکاری نام ہے۔ ایک نیا نام ضروری ہوا کیونکہ جاوا اسکرپٹ پر ٹریڈ مارک موجود ہے (اصل میں سن کے پاس ، اب اوریکل کے پاس) ۔ اس وقت ، موزیلا ان چند کمپنیوں میں سے ایک ہے جس کو جاوا اسکرپٹ کا نام سرکاری طور پر استعمال کرنے کی اجازت ہے کیونکہ اسے ایک لائسنس بہت پہلے ملا تھا۔ عام استعمال کے لئے ، یہ اصول لاگو ہوتے ہیں:
جاوا اسکرپٹ کے تخلیق کار ، برینڈن ایچ کے پاس زبان کو بہت تیزی سے بنانے کے علاوہ کوئی چارہ نہیں تھا (یا دوسری ، خراب ٹیکنالوجیز کو نیٹ اسکیپ نے اپنایا ہوتا) ۔ انہوں نے کئی پروگرامنگ زبانوں سے قرض لیا: جاوا (سنتاکس ، ابتدائی اقدار بمقابلہ اشیاء) ، اسکیم اور اے ڈبلیو کے (پہلی کلاس کے افعال) ، خود (پروٹو ٹائپ وراثت) ، اور پرل اور پایتون (سٹرنگز ، صفیں ، اور باقاعدہ اظہار) ۔
جاوا اسکرپٹ میں ECMAScript 3 تک استثناء کی ہینڈلنگ نہیں تھی ، جس کی وجہ سے یہ زبان اکثر خود بخود اقدار کو تبدیل کرتی ہے اور اکثر خاموشی سے ناکام ہوجاتی ہے۔ یہ ابتدائی طور پر استثناء نہیں پھینک سکتی تھی۔
ایک طرف ، جاوا اسکرپٹ میں عجیب و غریب خصوصیات ہیں اور اس میں کافی حد تک فعالیت کی کمی ہے (بلاک سکوپڈ متغیرات ، ماڈیولز ، ذیلی کلاسوں کی حمایت ، وغیرہ) ۔ دوسری طرف ، اس میں کئی طاقتور خصوصیات ہیں جو آپ کو ان مسائل کو حل کرنے کی اجازت دیتی ہیں۔ دوسری زبانوں میں ، آپ زبان کی خصوصیات سیکھتے ہیں۔ جاوا اسکرپٹ میں ، آپ اس کے بجائے اکثر پیٹرن سیکھتے ہیں۔
اس کے اثرات کو دیکھتے ہوئے ، یہ تعجب کی بات نہیں ہے کہ جاوا اسکرپٹ ایک پروگرامنگ اسٹائل کو قابل بناتا ہے جو فنکشنل پروگرامنگ (اعلی آرڈر کے افعال؛ بلٹ ان میپ ، کم کریں ، وغیرہ) اور آبجیکٹ پر مبنی پروگرامنگ (اعتراضات ، وراثت) کا مرکب ہے۔
اس سیکشن میں جاوا اسکرپٹ کے بنیادی نحو کے اصولوں کی وضاحت کی گئی ہے۔
نحو کی چند مثالیں:
// Two slashes start single-line comments
var x; // declaring a variable
x = 3 + y; // assigning a value to the variable `x`
foo(x, y); // calling function `foo` with parameters `x` and `y`
obj.bar(3); // calling method `bar` of object `obj`
// A conditional statement
if (x === 0) { // Is `x` equal to zero?
x = 123;
}
// Defining function `baz` with parameters `a` and `b`
function baz(a, b) {
return a + b;
}
برابر کے نشان کے دو مختلف استعمال پر غور کریں:
جاوا اسکرپٹ کے نحو کو سمجھنے کے لئے ، آپ کو یہ جاننا چاہئے کہ اس میں دو اہم نحو کی اقسام ہیں: بیانات اور اظہار:
var foo;
3 * 7
بیانات اور اظہار کے مابین فرق اس حقیقت سے واضح ہوتا ہے کہ جاوا اسکرپٹ میں بیان کے طور پر if-then-else
var x;
if (y >= 0) {
x = y;
} else {
x = -y;
}
یا ایک اظہار کے طور پر:
var x = y >= 0 ? y : -y;
آپ اس کے بعد ایک تقریب دلیل کے طور پر استعمال کر سکتے ہیں (لیکن سابقہ نہیں):
myFunction(y >= 0 ? y : -y)
آخر میں، جہاں کہیں بھی جاوا اسکرپٹ ایک بیان کی توقع کرتا ہے، آپ ایک اظہار بھی استعمال کرسکتے ہیں؛ مثال کے طور پر:
foo(7, 1);
پوری لائن ایک بیان ہے (ایک نام نہاد اظہار بیان) ، لیکن فنکشن کال foo(7, 1) ایک اظہار ہے.
سیمیکولن جاوا اسکرپٹ میں اختیاری ہیں۔ تاہم ، میں ان کو ہمیشہ شامل کرنے کی سفارش کرتا ہوں ، کیونکہ بصورت دیگر جاوا اسکرپٹ بیان کے اختتام کے بارے میں غلط اندازہ لگا سکتا ہے۔ تفصیلات خودکار سیمیکولن داخل کرنے میں بیان کی گئی ہیں۔
سیمیکولن بیانات کا اختتام کرتے ہیں ، لیکن بلاکس نہیں۔ ایک ایسا معاملہ ہے جہاں آپ کو بلاک کے بعد سیمیکولن نظر آئے گا: ایک فنکشن اظہار ایک ایسا اظہار ہے جو ایک بلاک کے ساتھ ختم ہوتا ہے۔ اگر اس طرح کا اظہار بیان میں آخر میں آتا ہے تو ، اس کے بعد سیمیکولن آتا ہے:
// Pattern: var _ = ___;
var x = 3 * 7;
var f = function () { }; // function expr. inside var decl.
جاوا اسکرپٹ میں دو قسم کے تبصرے ہیں: ایک سطر کے تبصرے اور کثیر سطر کے تبصرے۔ ایک سطر کے تبصرے // سے شروع ہوتے ہیں اور لائن کے آخر تک ختم ہوتے ہیں۔
x++; // single-line comment
کثیر سطر کے تبصرے /* اور */ کے ذریعہ محدود ہیں:
/* This is
a multiline
comment.
*/
جاوا اسکرپٹ میں متغیرات کو استعمال کرنے سے پہلے اعلان کیا جاتا ہے:
var foo; // declare variable `foo`
آپ ایک متغیر کا اعلان اور ایک ہی وقت میں ایک قدر تفویض کر سکتے ہیں:
var foo = 6;
آپ بھی ایک موجودہ متغیر کو ایک قدر تفویض کر سکتے ہیں:
foo = 4; // change variable `foo`
مرکب تفویض آپریٹرز جیسے += ہیں۔ مندرجہ ذیل دو تفویض مساوی ہیں:
x += 1;
x = x + 1;
شناخت کنندہ ایسے نام ہیں جو جاوا اسکرپٹ میں مختلف نحواتی کردار ادا کرتے ہیں۔ مثال کے طور پر ، متغیر کا نام شناخت کنندہ ہے۔ شناخت کنندہ بڑے اور چھوٹے حرفوں سے حساس ہیں۔
تقریبا ، شناخت کنندہ کا پہلا حرف کوئی بھی یونیکوڈ حرف ، ڈالر کا نشان ($) ، یا ایک underscore (_) ہوسکتا ہے۔ اس کے بعد کے حروف بھی کوئی بھی یونیکوڈ ہندسہ ہوسکتے ہیں۔ اس طرح ، مندرجہ ذیل تمام قانونی شناخت کنندہ ہیں:
arg0
_tmp
$elem
π
مندرجہ ذیل شناخت کار محفوظ الفاظ ہیں
مندرجہ ذیل تین شناخت کرنے والے الفاظ محفوظ الفاظ نہیں ہیں، لیکن آپ کو ان کے ساتھ ایسا ہی سلوک کرنا چاہئے:
آخر میں ، آپ کو معیاری عالمی متغیرات کے ناموں سے بھی دور رہنا چاہئے۔ آپ انہیں کسی بھی چیز کو توڑنے کے بغیر مقامی متغیرات کے لئے استعمال کرسکتے ہیں ، لیکن آپ کا کوڈ پھر بھی الجھن میں پڑ جاتا ہے۔
جاوا اسکرپٹ میں بہت سی اقدار ہیں جن کی ہم پروگرامنگ زبانوں سے توقع کرتے ہیں۔ بولینز ، نمبرز ، تاریں ، صفیں ، وغیرہ۔ جاوا اسکرپٹ میں تمام اقدار کی خصوصیات ہیں۔ ہر پراپرٹی میں ایک کلید (یا نام) اور ایک قدر ہوتی ہے۔ آپ پراپرٹیز کو ریکارڈ کے فیلڈز کی طرح سوچ سکتے ہیں۔ آپ کسی پراپرٹی کو پڑھنے کے لئے ڈاٹ (.) آپریٹر کا استعمال کرتے ہیں:
value.propKey
مثال کے طور پر ، سٹرنگ
> var str = 'abc';
> str.length
3
سابقہ بھی لکھا جا سکتا ہے:
> 'abc'.length
3
The dot operator is also used to assign a value to a property:
> var obj = {}; // empty object
> obj.foo = 123; // create property `foo`, set it to 123
123
> obj.foo
123
اور آپ اسے طریقوں کو بلانے کے لئے استعمال کر سکتے ہیں:
> 'hello'.toUpperCase()
'HELLO'
پچھلی مثال میں، ہم نے قدر
جاوا اسکرپٹ قدروں کے درمیان کسی حد تک اپنی مرضی کے مطابق فرق کرتا ہے:
> var obj1 = {}; // an empty object
> var obj2 = {}; // another empty object
> obj1 === obj2
false
> obj1 === obj1
true
اس کے برعکس ، ایک ہی قدر کوڈ کرنے والے تمام ابتدائی اقدار کو ایک جیسا سمجھا جاتا ہے:
> var prim1 = 123;
> var prim2 = 123;
> prim1 === prim2
true
اگلے دو حصوں میں ابتدائی اقدار اور اشیاء کو مزید تفصیل سے بیان کیا گیا ہے۔
مندرجہ ذیل تمام ابتدائی اقدار ہیں (یا مختصر طور پر ابتدائی):
ابتدائیوں کی مندرجہ ذیل خصوصیات ہیں:
> 3 === 3
true
> 'abc' === 'abc'
true
### ہمیشہ غیر متغیر ## خصوصیات کو تبدیل، شامل، یا ہٹا نہیں کیا جا سکتا:
> var str = 'abc';
> str.length = 1; // try to change property `length`
> str.length // ⇒ no effect
3
> str.foo = 3; // try to create property `foo`
> str.foo // ⇒ no effect, unknown property
undefined
(ایک نامعلوم پراپرٹی کو پڑھنا ہمیشہ غیر متعین لوٹتا ہے.)
تمام غیر ابتدائی اقدار اشیاء ہیں۔ اشیاء کی سب سے عام اقسام یہ ہیں:
{
firstName: 'Jane',
lastName: 'Doe'
}
پچھلے آبجیکٹ کی دو خصوصیات ہیں: پراپرٹی firstName کی قدر
[ 'apple', 'banana', 'cherry' ]
پچھلی صف میں تین عناصر ہیں جن تک عددی اشاریہ جات کے ذریعے رسائی حاصل کی جاسکتی ہے۔ مثال کے طور پر
/^a+b+$/
اشیاء کی مندرجہ ذیل خصوصیات ہیں:
شناختوں کا موازنہ کیا جاتا ہے۔ ہر قدر کی اپنی شناخت ہوتی ہے:
> ({} === {}) // two different empty objects
false
> var obj1 = {};
> var obj2 = obj1;
> obj1 === obj2
true
آپ عام طور پر آزادانہ طور پر خصوصیات کو تبدیل، شامل، اور ہٹا سکتے ہیں (واحد اشیاء دیکھیں):
> var obj = {};
> obj.foo = 123; // add property `foo`
> obj.foo
123
زیادہ تر پروگرامنگ زبانوں میں گمشدہ معلومات کی نشاندہی کرنے والے اقدار ہوتے ہیں۔ جاوا اسکرپٹ میں دو ایسے
> var foo;
> foo
undefined
لاپتہ پیرامیٹرز غیر متعین ہیں:
> function f(x) { return x }
> f()
undefined
اگر آپ ایک غیر موجود پراپرٹی پڑھتے ہیں، تو آپ غیر متعین ہو جاتے ہیں:
> var obj = {}; // empty object
> obj.foo
undefined
undefined اور null کی کوئی خصوصیات نہیں ہیں، یہاں تک کہ معیاری طریقے جیسے toString().
افعال عام طور پر آپ کو غیر متعین یا صفر کے ذریعے ایک لاپتہ قدر کی نشاندہی کرنے کی اجازت دیتے ہیں۔ آپ ایک واضح چیک کے ذریعے بھی ایسا ہی کرسکتے ہیں:
if (x === undefined || x === null) {
...
}
آپ اس حقیقت کا بھی فائدہ اٹھا سکتے ہیں کہ غیر متعین اور null دونوں کو غلط سمجھا جاتا ہے:
if (!x) {
...
}
false، 0، NaN، اور
اقدار کی درجہ بندی کے لئے دو آپریٹرز ہیں: typeof بنیادی طور پر ابتدائی اقدار کے لئے استعمال کیا جاتا ہے، جبکہ instanceof اشیاء کے لئے استعمال کیا جاتا ہے. اس طرح لگتا ہے:
typeof value
یہ ایک تار واپس کرتا ہے جو قدر کی
> typeof true
'boolean'
> typeof 'abc'
'string'
> typeof {} // empty object literal
'object'
> typeof [] // empty array literal
'object'
مندرجہ ذیل ٹیبل میں typeof کے تمام نتائج درج ہیں:
typeof null returning
مثال اس طرح نظر آتی ہے:
value instanceof Constr
یہ سچ لوٹاتا ہے اگر قدر ایک ایسی چیز ہے جو کنسٹرکٹر کنسٹرکٹر کے ذریعہ بنائی گئی ہے۔ یہاں کچھ مثالیں ہیں:
> var b = new Bar(); // object created by constructor Bar
> b instanceof Bar
true
> {} instanceof Object
true
> [] instanceof Array
true
> [] instanceof Object // Array is a subconstructor of Object
true
> undefined instanceof Object
false
> null instanceof Object
false
ابتدائی بولین قسم میں درست اور غلط اقدار شامل ہیں۔ مندرجہ ذیل آپریٹرز بولینز تیار کرتے ہیں:
جب بھی جاوا اسکرپٹ بولین ویلیو کی توقع کرتا ہے (مثال کے طور پر ، اگر بیان کی شرط کے لئے) ، کوئی بھی قدر استعمال کی جاسکتی ہے۔ اس کی ترجمانی یا تو درست یا غلط کی جائے گی۔ مندرجہ ذیل اقدار کو غلط کے طور پر تشریح کیا جاتا ہے:
دیگر تمام اقدار (بشمول تمام اشیاء!) درست سمجھا جاتا ہے۔ غلط کے طور پر تشریح کردہ اقدار کو غلط کہا جاتا ہے ، اور سچ کے طور پر تشریح کردہ اقدار کو سچ کہا جاتا ہے۔ بولین ((() ، جسے بطور فنکشن کہا جاتا ہے ، اس کے پیرامیٹر کو بولین میں تبدیل کرتا ہے۔ آپ اس کا استعمال کسی قدر کی تشریح کے طریقہ کار کو جانچنے کے لئے کرسکتے ہیں:
> Boolean(undefined)
false
> Boolean(0)
false
> Boolean(3)
true
> Boolean({}) // empty object
true
> Boolean([]) // empty array
true
جاوا اسکرپٹ میں بائنری منطقی آپریٹر شارٹ سرکٹ ہوتے ہیں۔ یعنی ، اگر نتیجہ کا تعین کرنے کے لئے پہلا آپریٹر کافی ہے تو ، دوسرا آپریٹر قابل قدر نہیں ہے۔ مثال کے طور پر ، مندرجہ ذیل اظہار میں ، فنکشن foo() کو کبھی نہیں کہا جاتا ہے۔
false && foo()
true || foo()
مزید برآں ، بائنری منطقی آپریٹرز ان کے کسی ایک آپریٹر کو واپس کرتے ہیں جو بولین ہوسکتا ہے یا نہیں ہوسکتا ہے۔ سچائی کی جانچ پڑتال کا استعمال اس بات کا تعین کرنے کے لئے کیا جاتا ہے کہ کون سا:
اگر پہلا آپریڈ غلط ہے، تو اسے واپس کریں. دوسری صورت میں، دوسرا آپریڈ واپس کریں:
> NaN && 'abc'
NaN
> 123 && 'abc'
'abc'
اگر پہلا آپریڈ درست ہے تو اسے واپس کریں۔ بصورت دیگر ، دوسرا آپریڈ واپس کریں:
> 'abc' || 123
'abc'
> '' || 123
123
جاوا اسکرپٹ میں دو طرح کی مساوات ہے:
عام مساوات (بہت) بہت سی اقدار کو برابر سمجھتی ہے (تفصیلات کو نارمل (لنینٹ) مساوات (== ،!=) میں بیان کیا گیا ہے) ، جو کیڑے چھپا سکتی ہے۔ لہذا ، ہمیشہ سخت مساوات کا استعمال کرنے کی سفارش کی جاتی ہے۔
جاوا اسکرپٹ میں تمام اعداد فلوٹنگ نقطہ ہیں:
> 1 === 1.0
true
خصوصی نمبروں میں درج ذیل شامل ہیں:
NaN (
> Number('xyz') // 'xyz' can’t be converted to a number
NaN
لامحدود بھی زیادہ تر ایک غلطی کی قیمت:
> 3 / 0
Infinity
> Math.pow(2, 1024) // number too large
Infinity
لامحدود کسی بھی دوسرے نمبر سے بڑا ہے (سوائے NaN کے) ۔ اسی طرح ، - لامحدود کسی بھی دوسرے نمبر سے چھوٹا ہے (سوائے NaN کے) ۔ اس سے یہ نمبر بطور ڈیفالٹ اقدار کارآمد ہوجاتے ہیں (جیسے ، جب آپ کم سے کم یا زیادہ سے زیادہ تلاش کر رہے ہیں) ۔
جاوا اسکرپٹ میں مندرجہ ذیل ریاضیاتی آپریٹرز ہیں (دیکھیں ریاضیاتی آپریٹرز):
گلوبل آبجیکٹ ریاضی (دیکھیں ریاضی) افعال کے ذریعے زیادہ ریاضیاتی آپریشن فراہم کرتا ہے۔
جاوا اسکرپٹ میں بٹ ویز آپریشنز کے لئے آپریٹرز بھی ہیں (مثال کے طور پر ، بٹ ویز اور؛ دیکھیں بٹ ویز آپریٹرز).
اسٹرنگز کو براہ راست اسٹرنگ لٹریلز کے ذریعے بنایا جاسکتا ہے۔ ان لٹریلز کو سنگل یا ڈبل کوٹس کے ذریعہ محدود کیا جاتا ہے۔ بیک سلیش () حروف سے بچ جاتا ہے اور کچھ کنٹرول حروف تیار کرتا ہے۔ یہاں کچھ مثالیں ہیں:
'abc'
"abc"
'Did she say "Hello"?'
"Did she say \"Hello\"?"
'That\'s nice!'
"That's nice!"
'Line 1\nLine 2' // newline
'Backlash: \\'
واحد حروف مربع قوسین کے ذریعے قابل رسائی ہیں:
> var str = 'abc';
> str[1]
'b'
پراپرٹی لمبائی سٹرنگ میں حروف کی تعداد شمار کرتا ہے:
> 'abc'.length
3
تمام ابتدائیوں کی طرح، سٹرنگز غیر متغیر ہیں؛ اگر آپ کسی موجودہ کو تبدیل کرنا چاہتے ہیں تو آپ کو ایک نئی سٹرنگ بنانے کی ضرورت ہے.
سٹرنگز کو پلس (+) آپریٹر کے ذریعے منسلک کیا جاتا ہے جو دوسرے آپریڈ کو سٹرنگ میں تبدیل کرتا ہے اگر آپریڈ میں سے ایک سٹرنگ ہے:
> var messageCount = 3;
> 'You have ' + messageCount + ' messages'
'You have 3 messages'
متعدد مراحل میں تاروں کو مربوط کرنے کے لئے ، += آپریٹر استعمال کریں:
> var str = '';
> str += 'Multiple ';
> str += 'pieces ';
> str += 'are concatenated.';
> str
'Multiple pieces are concatenated.'
اسٹرنگ میں بہت سارے مفید طریقے ہیں (اسٹرنگ پروٹوٹائپ کے طریقے دیکھیں) ۔ یہاں کچھ مثالیں ہیں:
> 'abc'.slice(1) // copy a substring
'bc'
> 'abc'.slice(1, 2)
'b'
> '\t xyz '.trim() // trim whitespace
'xyz'
> 'mjölnir'.toUpperCase()
'MJÖLNIR'
> 'abc'.indexOf('b') // find a string
1
> 'abc'.indexOf('x')
-1
جاوا اسکرپٹ میں شرائط اور لوپس کو مندرجہ ذیل حصوں میں متعارف کرایا گیا ہے۔
اگر بیان میں ایک then شق اور ایک اختیاری else شق ہے جو ایک بولین شرط پر منحصر ہے:
if (myvar === 0) {
// then
}
if (myvar === 0) {
// then
} else {
// else
}
if (myvar === 0) {
// then
} else if (myvar === 1) {
// else-if
} else if (myvar === 2) {
// else-if
} else {
// else
}
میں ہمیشہ برائٹس کا استعمال کرنے کی سفارش کرتا ہوں (وہ صفر یا اس سے زیادہ بیانات کے بلاکس کی نشاندہی کرتے ہیں) ۔ لیکن اگر کوئی شق صرف ایک ہی بیان ہے تو آپ کو ایسا کرنے کی ضرورت نہیں ہے (ایسا ہی کنٹرول فلو کے بیانات کے لئے بھی ہوتا ہے اور جبکہ):
if (x < 0) return -x;
مندرجہ ذیل ایک سوئچ کمانڈ ہے۔ پھل کی قدر فیصلہ کرتی ہے کہ کون سا کیس عمل میں لایا جاتا ہے:
switch (fruit) {
case 'banana':
// ...
break;
case 'apple':
// ...
break;
default: // all other cases
// ...
}
کے لئے لوپ مندرجہ ذیل شکل ہے:
for (⟦«init»⟧; ⟦«condition»⟧; ⟦«post_iteration»⟧)
«statement»
init لوپ کے آغاز میں عمل میں لایا جاتا ہے۔ condition ہر لوپ تکرار سے پہلے چیک کیا جاتا ہے۔ اگر یہ غلط ہوجاتا ہے تو ، پھر لوپ ختم ہوجاتا ہے۔ post_iteration ہر لوپ تکرار کے بعد عمل میں لایا جاتا ہے۔
یہ مثال کنسول پر صف arr کے تمام عناصر پرنٹ کرتی ہے:
for (var i=0; i < arr.length; i++) {
console.log(arr[i]);
}
جبکہ لوپ اس کے جسم پر لوپ جاری ہے جب تک اس کی حالت برقرار ہے:
// Same as for loop above:
var i = 0;
while (i < arr.length) {
console.log(arr[i]);
i++;
}
جبکہ لوپ اس کے جسم پر لوپ جاری رہتا ہے جب تک کہ اس کی حالت برقرار رہتی ہے۔ چونکہ حالت جسم کے بعد آتی ہے ، لہذا جسم کو ہمیشہ کم از کم ایک بار انجام دیا جاتا ہے:
do {
// ...
} while (condition);
تمام لوپ میں:
فنکشن کی وضاحت کا ایک طریقہ فنکشن کے اعلان کے ذریعے ہے:
function add(param1, param2) {
return param1 + param2;
}
پچھلا کوڈ ایک فنکشن کی وضاحت کرتا ہے، شامل کریں، جس میں دو پیرامیٹرز ہیں، پیرامیٹر 1 اور پیرامیٹر 2، اور دونوں پیرامیٹرز کا مجموعہ واپس کرتا ہے۔ آپ اس فنکشن کو اس طرح کہتے ہیں:
> add(6, 1)
7
> add('a', 'b')
'ab'
شامل کرنے کا ایک اور طریقہ وضاحت کرنا ہے () ایک متغیر شامل کرنے کے لئے ایک فنکشن اظہار تفویض کر رہا ہے:
var add = function (param1, param2) {
return param1 + param2;
};
ایک فنکشن اظہار ایک قدر پیدا کرتا ہے اور اس طرح براہ راست دوسرے افعال کو دلائل کے طور پر افعال کو منتقل کرنے کے لئے استعمال کیا جا سکتا ہے:
someOtherFunction(function (p1, p2) { ... });
فنکشن کے اعلانات کو مکمل طور پر موجودہ دائرہ کار کے آغاز میں منتقل کردیا جاتا ہے۔ اس سے آپ کو بعد میں اعلان کردہ افعال کا حوالہ دینے کی اجازت ملتی ہے۔
function foo() {
bar(); // OK, bar is hoisted
function bar() {
...
}
}
نوٹ کریں کہ جبکہ var اعلانات بھی ہائیسڈ ہیں (دیکھیں متغیرات ہائیسڈ ہیں) ، ان کی طرف سے کارکردگی کا مظاہرہ تفویض نہیں ہیں:
function foo() {
bar(); // Not OK, bar is still undefined
var bar = function () {
// ...
};
}
آپ جاوا اسکرپٹ میں کسی بھی فنکشن کو اپنی مرضی کے مطابق تعداد میں دلائل کے ساتھ کال کرسکتے ہیں۔ زبان کبھی بھی شکایت نہیں کرے گی۔ تاہم ، یہ خصوصی متغیر دلائل کے ذریعہ تمام پیرامیٹرز کو دستیاب کردے گی۔ دلائل ایک صف کی طرح نظر آتے ہیں ، لیکن اس میں کسی بھی صف کے طریقے نہیں ہیں:
> function f() { return arguments }
> var args = f('a', 'b', 'c');
> args.length
3
> args[0] // read element at index 0
'a'
آئیے مندرجہ ذیل فنکشن کا استعمال کرتے ہیں کہ جاوا اسکرپٹ میں بہت زیادہ یا بہت کم پیرامیٹرز کو کس طرح سنبھالا جاتا ہے (فنکشن toArray() کو ایک صف میں دلیلوں کو تبدیل کرنے میں دکھایا گیا ہے):
function f(x, y) {
console.log(x, y);
return toArray(arguments);
}
اضافی پیرامیٹرز کو نظر انداز کیا جائے گا (سوائے دلیلوں کے):
> f('a', 'b', 'c')
a b
[ 'a', 'b', 'c' ]
غائب پیرامیٹرز کی قدر غیر متعین ہو جائے گا:
> f('a')
a undefined
[ 'a' ]
> f()
undefined undefined
[]
مندرجہ ذیل پیرامیٹرز کو ڈیفالٹ اقدار تفویض کرنے کے لئے ایک عام پیٹرن ہے:
function pair(x, y) {
x = x || 0; // (1)
y = y || 0;
return [ x, y ];
}
لائن (1) میں ، اگر آپریٹر x درست ہے (خالی ، غیر متعین وغیرہ نہیں) تو آپریٹر واپس کرتا ہے۔ بصورت دیگر ، یہ دوسرا آپریٹر واپس کرتا ہے:
> pair()
[ 0, 0 ]
> pair(3)
[ 3, 0 ]
> pair(3, 5)
[ 3, 5 ]
اگر آپ ایک arity (ایک مخصوص پیرامیٹرز کی تعداد) نافذ کرنا چاہتے ہیں تو ، آپ کو چیک کر سکتے ہیں arguments.length:
function pair(x, y) {
if (arguments.length !== 2) {
throw new Error('Need exactly 2 arguments');
}
...
}
arguments ایک صف نہیں ہے ، یہ صرف صف کی طرح ہے (دیکھیں صف کی طرح اشیاء اور عمومی طریقے) ۔ اس کی ایک پراپرٹی کی لمبائی ہے ، اور آپ مربع قوسین میں انڈیکس کے ذریعے اس کے عناصر تک رسائی حاصل کرسکتے ہیں۔ تاہم ، آپ عناصر کو نہیں ہٹا سکتے ہیں یا اس پر کسی بھی صف کے طریقوں کو طلب نہیں کرسکتے ہیں۔ اس طرح ، بعض اوقات آپ کو دلیلوں کو صف میں تبدیل کرنے کی ضرورت ہوتی ہے ، جو مندرجہ ذیل فنکشن کرتا ہے (اس کی وضاحت صف کی طرح اشیاء اور عمومی طریقوں میں کی گئی ہے):
function toArray(arrayLikeObject) {
return Array.prototype.slice.call(arrayLikeObject);
}
استثناءات کو سنبھالنے کا سب سے عام طریقہ (باب 14 دیکھیں) مندرجہ ذیل ہے:
function getPerson(id) {
if (id < 0) {
throw new Error('ID must not be negative: '+id);
}
return { id: id }; // normally: retrieved from database
}
function getPersons(ids) {
var result = [];
ids.forEach(function (id) {
try {
var person = getPerson(id);
result.push(person);
} catch (exception) {
console.log(exception);
}
});
return result;
}
try شق اہم کوڈ کے گرد گھومتی ہے ، اور catch شق پر عملدرآمد ہوتا ہے اگر کسی استثناء کو try شق کے اندر پھینک دیا جاتا ہے۔ پچھلے کوڈ کا استعمال کرتے ہوئے:
> getPersons([2, -5, 137])
[Error: ID must not be negative: -5]
[ { id: 2 }, { id: 137 } ]
سخت موڈ (سخت موڈ دیکھیں) زیادہ انتباہات کو قابل بناتا ہے اور جاوا اسکرپٹ کو ایک صاف زبان بناتا ہے (غیر سخت موڈ کو کبھی کبھی
'use strict';
آپ فی فنکشن سخت موڈ کو بھی فعال کر سکتے ہیں:
function functionInStrictMode() {
'use strict';
}
جاوا اسکرپٹ میں، آپ کو ان کا استعمال کرنے سے پہلے var کے ذریعے متغیرات کا اعلان:
> var x;
> x
undefined
> y
ReferenceError: y is not defined
آپ ایک واحد var بیان کے ساتھ کئی متغیرات کا اعلان اور ابتدائی کر سکتے ہیں:
var x = 1, y = 2, z = 3;
لیکن میں فی متغیر ایک بیان کا استعمال کرنے کی سفارش کرتا ہوں (اس کی وجہ نحو میں بیان کی گئی ہے۔ اس طرح میں پچھلے بیان کو دوبارہ لکھوں گا:
var x = 1;
var y = 2;
var z = 3;
ہائسٹنگ کی وجہ سے (دیکھیں متغیرات ہائیسٹڈ ہیں) ، عام طور پر کسی فنکشن کے آغاز میں متغیرات کا اعلان کرنا بہتر ہوتا ہے۔
متغیر کا دائرہ کار ہمیشہ مکمل فنکشن ہوتا ہے (موجودہ بلاک کے برعکس) ۔ مثال کے طور پر:
function foo() {
var x = -512;
if (x < 0) { // (1)
var tmp = -x;
...
}
console.log(tmp); // 512
}
ہم دیکھ سکتے ہیں کہ متغیر tmp لائن (1) میں شروع ہونے والے بلاک تک محدود نہیں ہے۔ یہ فنکشن کے اختتام تک موجود ہے۔
ہر متغیر کے اعلان کو اٹھایا جاتا ہے: اعلان کو فنکشن کے آغاز میں منتقل کیا جاتا ہے ، لیکن اس کی تفویضات کو برقرار رکھا جاتا ہے۔ مثال کے طور پر ، مندرجہ ذیل فنکشن میں لائن (1) میں متغیر کے اعلان پر غور کریں:
function foo() {
console.log(tmp); // undefined
if (false) {
var tmp = 3; // (1)
}
}
اندرونی طور پر، پچھلے فنکشن کو اس طرح انجام دیا جاتا ہے:
function foo() {
var tmp; // hoisted declaration
console.log(tmp);
if (false) {
tmp = 3; // assignment stays put
}
}
ہر فنکشن اس کے آس پاس کے افعال کی متغیرات سے منسلک رہتا ہے ، یہاں تک کہ جب یہ اس دائرہ کار سے باہر نکل جاتا ہے جس میں یہ تخلیق کیا گیا تھا۔ مثال کے طور پر:
function createIncrementor(start) {
return function () { // (1)
start++;
return start;
}
}
لائن (1) میں شروع ہونے والا فنکشن اس سیاق و سباق کو چھوڑ دیتا ہے جس میں یہ تخلیق کیا گیا تھا ، لیکن شروع کے رواں ورژن سے منسلک رہتا ہے:
> var inc = createIncrementor(5);
> inc()
6
> inc()
7
> inc()
8
بندش ایک فنکشن ہے جس میں اس کے آس پاس کے دائرہ کار کے متغیرات کے ساتھ رابطے شامل ہیں۔ اس طرح ، جو کچھ تخلیقIncrementor() لوٹتا ہے وہ بندش ہے۔
بعض اوقات آپ ایک نیا متغیر دائرہ کار متعارف کرانا چاہتے ہیں۔ مثال کے طور پر ، متغیر کو عالمی بننے سے روکنے کے لئے۔ جاوا اسکرپٹ میں ، آپ ایسا کرنے کے لئے بلاک استعمال نہیں کرسکتے ہیں۔ آپ کو ایک فنکشن استعمال کرنا ہوگا۔ لیکن بلاک جیسے انداز میں فنکشن استعمال کرنے کے لئے ایک نمونہ ہے۔ اسے IIFE کہا جاتا ہے (فوری طور پر فنکشن اظہار ، تلفظ
(function () { // open IIFE
var tmp = ...; // not a global variable
}()); // close IIFE
پچھلی مثال کو بالکل اسی طرح ٹائپ کرنا یقینی بنائیں (تبصرے کے علاوہ) ۔ ایک IIFE ایک فنکشن اظہار ہے جو آپ کی وضاحت کے فورا بعد بلایا جاتا ہے۔ فنکشن کے اندر ، ایک نیا دائرہ موجود ہے ، جس سے tmp کو عالمی بننے سے روکتا ہے۔ IIFE کے ذریعے نیا دائرہ متعارف کرانے سے مشورہ کریں IIFEs کے بارے میں تفصیلات کے لئے.
بندشیں بیرونی متغیرات کے ساتھ اپنے رابطے کو برقرار رکھتی ہیں، جو کبھی کبھی آپ کی خواہش نہیں ہے:
var result = [];
for (var i=0; i < 5; i++) {
result.push(function () { return i }); // (1)
}
console.log(result[1]()); // 5 (not 1)
console.log(result[3]()); // 5 (not 3)
صف (1) میں واپس آنے والی قیمت ہمیشہ i کی موجودہ قیمت ہوتی ہے ، نہ کہ اس کی قیمت جب فنکشن بنتا تھا۔ لوپ ختم ہونے کے بعد ، i کی قیمت 5 ہوتی ہے ، یہی وجہ ہے کہ صف میں موجود تمام افعال اس قدر کی واپسی کرتے ہیں۔ اگر آپ چاہتے ہیں کہ لائن (1) میں فنکشن i کی موجودہ قیمت کا اسنیپ شاٹ حاصل کرے تو ، آپ IIFE استعمال کرسکتے ہیں:
for (var i=0; i < 5; i++) {
(function () {
var i2 = i; // copy current i
result.push(function () { return i2 });
}());
}
اس حصے میں جاوا اسکرپٹ کے دو بنیادی آبجیکٹ پر مبنی میکانزم کا احاطہ کیا گیا ہے: سنگل آبجیکٹ اور کنسٹرکٹر (جو اشیاء کے لئے فیکٹری ہیں ، جو دوسری زبانوں میں کلاسوں کی طرح ہیں) ۔
تمام اقدار کی طرح ، اشیاء کی خصوصیات ہیں۔ آپ ، حقیقت میں ، کسی چیز کو خصوصیات کا ایک مجموعہ سمجھ سکتے ہیں ، جہاں ہر پراپرٹی ایک (کلید ، قیمت) جوڑی ہے۔ کلید ایک تار ہے ، اور قدر کسی بھی جاوا اسکرپٹ کی قدر ہے۔
جاوا اسکرپٹ میں، آپ براہ راست سادہ اشیاء بنا سکتے ہیں، جس کے ذریعے اعتراض کی لٹریل:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
پچھلے آبجیکٹ میں پراپرٹیز کا نام اور بیان ہے۔ آپ (
> jane.name // get
'Jane'
> jane.name = 'John'; // set
> jane.newProperty = 'abc'; // property created automatically
فنکشن ویلیوڈ پراپرٹیز جیسے ڈسپلے کو میتھڈ کہا جاتا ہے۔ وہ اس کا استعمال اس شے کا حوالہ دینے کے لئے کرتے ہیں جس کا استعمال ان کو کال کرنے کے لئے کیا گیا تھا:
> jane.describe() // call method
'Person named John'
> jane.name = 'Jane';
> jane.describe()
'Person named Jane'
میں آپریٹر چیک کرتا ہے کہ آیا کوئی پراپرٹی موجود ہے:
> 'newProperty' in jane
true
> 'foo' in jane
false
اگر آپ ایسی پراپرٹی پڑھتے ہیں جو موجود نہیں ہے تو ، آپ کو قدر undefined مل جاتی ہے۔ لہذا پچھلے دو چیک بھی اس طرح انجام دیئے جاسکتے ہیں:
> jane.newProperty !== undefined
true
> jane.foo !== undefined
false
حذف آپریٹر ایک پراپرٹی کو ہٹا دیتا ہے:
> delete jane.newProperty
true
> 'newProperty' in jane
false
ایک پراپرٹی کلید کوئی بھی سٹرنگ ہوسکتی ہے۔ اب تک ، ہم نے پراپرٹی کیز کو آبجیکٹ لٹریل میں اور ڈاٹ آپریٹر کے بعد دیکھا ہے۔ تاہم ، آپ انہیں صرف اس طرح استعمال کرسکتے ہیں اگر وہ شناخت کنندہ ہیں (دیکھیں شناخت کنندہ اور متغیر نام) ۔ اگر آپ دیگر تاروں کو بطور چابیاں استعمال کرنا چاہتے ہیں تو ، آپ کو انہیں آبجیکٹ لٹریل میں حوالہ دینا ہوگا اور پراپرٹی حاصل کرنے اور سیٹ کرنے کے لئے مربع قوسین کا استعمال کرنا ہوگا:
> var obj = { 'not an identifier': 123 };
> obj['not an identifier']
123
> obj['not an identifier'] = 456;
مربع قوسین بھی آپ کو ایک پراپرٹی کی کلید کا حساب کرنے کی اجازت دیتے ہیں:
> var obj = { hello: 'world' };
> var x = 'hello';
> obj[x]
'world'
> obj['hel'+'lo']
'world'
اگر آپ کسی طریقہ کار کو نکالتے ہیں تو ، یہ آبجیکٹ سے اپنا تعلق کھو دیتا ہے۔ خود ہی ، فنکشن اب کوئی طریقہ کار نہیں ہے ، اور اس کی قدر غیر متعین ہے (سخت موڈ میں) ۔
مثال کے طور پر، چلو پہلے اعتراض جین پر واپس جائیں:
'use strict';
var jane = {
name: 'Jane',
describe: function () {
return 'Person named '+this.name;
}
};
ہم طریقہ بیان کو جین سے نکالنا چاہتے ہیں ، اسے متغیر فنکشن میں ڈالیں ، اور اسے کال کریں۔ تاہم ، یہ کام نہیں کرتا:
> var func = jane.describe;
> func()
TypeError: Cannot read property 'name' of undefined
اس کا حل یہ ہے کہ تمام افعال کے پاس پابند () طریقہ استعمال کریں۔ یہ ایک نیا فنکشن بناتا ہے جس کی ہمیشہ دی گئی قیمت ہوتی ہے:
> var func2 = jane.describe.bind(jane);
> func2()
'Person named Jane'
ہر فنکشن کا اپنا خصوصی متغیر ہوتا ہے۔ اگر آپ کسی طریقہ کار کے اندر کسی فنکشن کو گھساتے ہیں تو یہ تکلیف دہ ہے ، کیونکہ آپ فنکشن سے اس طریقہ کار تک رسائی حاصل نہیں کرسکتے ہیں۔ مندرجہ ذیل ایک مثال ہے جہاں ہم ایک صف میں تکرار کرنے کے لئے فنکشن کے ساتھ ہر ایک کو کال کرتے ہیں:
var jane = {
name: 'Jane',
friends: [ 'Tarzan', 'Cheeta' ],
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
// `this` is undefined here
console.log(this.name+' says hi to '+friend);
});
}
}
logHiToFriends کو کال کرنے سے ایک غلطی پیدا ہوتی ہے:
> jane.logHiToFriends()
TypeError: Cannot read property 'name' of undefined
آئیے اس کو ٹھیک کرنے کے دو طریقے دیکھیں۔ سب سے پہلے، ہم اسے ایک مختلف متغیر میں ذخیرہ کر سکتے ہیں:
logHiToFriends: function () {
'use strict';
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name+' says hi to '+friend);
});
}
یا، forEach ایک دوسرا پیرامیٹر ہے جو آپ کو اس کے لئے ایک قدر فراہم کرنے کی اجازت دیتا ہے:
logHiToFriends: function () {
'use strict';
this.friends.forEach(function (friend) {
console.log(this.name+' says hi to '+friend);
}, this);
}
افعال کے تاثرات اکثر جاوا اسکرپٹ میں افعال کالوں میں دلائل کے طور پر استعمال ہوتے ہیں۔ جب آپ ان افعال کے اظہار میں سے کسی سے اس کا حوالہ دیتے ہیں تو ہمیشہ محتاط رہیں۔
اب تک ، آپ سوچ سکتے ہیں کہ جاوا اسکرپٹ آبجیکٹ صرف تاروں سے اقدار تک نقشے ہیں ، یہ تصور جاوا اسکرپٹ کے آبجیکٹ لٹریل سے تجویز کیا گیا ہے ، جو دیگر زبانوں کے نقشہ / لغت کے لٹریل کی طرح نظر آتے ہیں۔ تاہم ، جاوا اسکرپٹ آبجیکٹ ایک ایسی خصوصیت کی بھی حمایت کرتے ہیں جو واقعی آبجیکٹ پر مبنی ہے: وراثت۔ یہ سیکشن مکمل طور پر وضاحت نہیں کرتا ہے کہ جاوا اسکرپٹ وراثت کیسے کام کرتی ہے ، لیکن یہ آپ کو شروع کرنے کے لئے ایک آسان نمونہ دکھاتا ہے۔ اگر آپ مزید جاننا چاہتے ہیں تو باب 17 سے رجوع کریں۔
// Set up instance data
function Point(x, y) {
this.x = x;
this.y = y;
}
// Methods
Point.prototype.dist = function () {
return Math.sqrt(this.x*this.x + this.y*this.y);
};
ہم دیکھ سکتے ہیں کہ ایک کنسٹرکٹر کے دو حصے ہیں۔ سب سے پہلے ، فنکشن پوائنٹ مثال کے اعداد و شمار کو ترتیب دیتا ہے۔ دوسرا ، پراپرٹی پوائنٹ.پروٹوٹائپ میں طریقوں کے ساتھ ایک آبجیکٹ ہوتا ہے۔ سابقہ ڈیٹا ہر مثال کے لئے مخصوص ہے ، جبکہ مؤخر الذکر کا ڈیٹا تمام مثالوں میں مشترکہ ہے۔
پوائنٹ استعمال کرنے کے لیے، ہم اسے نئے آپریٹر کے ذریعے بلاتے ہیں:
> var p = new Point(3, 5);
> p.x
3
> p.dist()
5.830951894845301
p نقطہ کی ایک مثال ہے:
> p instanceof Point
true
صفیں عناصر کی ترتیب ہیں جن تک صفر سے شروع ہونے والے انٹیجر انڈیکس کے ذریعے رسائی حاصل کی جاسکتی ہے۔
صفوں کو تخلیق کرنے کے لئے صفوں کے لٹریل مفید ہیں:
> var arr = [ 'a', 'b', 'c' ];
پچھلے صف میں تین عناصر ہیں: ڈور
> arr[0]
'a'
> arr[0] = 'x';
> arr
[ 'x', 'b', 'c' ]
لمبائی کی خصوصیت اس بات کی نشاندہی کرتی ہے کہ کسی صف میں کتنے عناصر ہیں۔ آپ اس کا استعمال عناصر کو شامل کرنے اور عناصر کو ہٹانے کے لئے کرسکتے ہیں۔
> var arr = ['a', 'b'];
> arr.length
2
> arr[arr.length] = 'c';
> arr
[ 'a', 'b', 'c' ]
> arr.length
3
> arr.length = 1;
> arr
[ 'a' ]
in آپریٹر صفوں کے لئے بھی کام کرتا ہے:
> var arr = [ 'a', 'b', 'c' ];
> 1 in arr // is there an element at index 1?
true
> 5 in arr // is there an element at index 5?
false
نوٹ کریں کہ صفیں آبجیکٹ ہیں اور اس طرح آبجیکٹ کی خصوصیات رکھ سکتی ہیں:
> var arr = [];
> arr.foo = 123;
> arr.foo
123
صفوں میں بہت سارے طریقے ہیں (آرری پروٹوٹائپ طریقوں کو دیکھیں) ۔ یہاں کچھ مثالیں ہیں:
> var arr = [ 'a', 'b', 'c' ];
> arr.slice(1, 2) // copy elements
[ 'b' ]
> arr.slice(1)
[ 'b', 'c' ]
> arr.push('x') // append an element
4
> arr
[ 'a', 'b', 'c', 'x' ]
> arr.pop() // remove last element
'x'
> arr
[ 'a', 'b', 'c' ]
> arr.shift() // remove first element
'a'
> arr
[ 'b', 'c' ]
> arr.unshift('x') // prepend an element
3
> arr
[ 'x', 'b', 'c' ]
> arr.indexOf('b') // find the index of an element
1
> arr.indexOf('y')
-1
> arr.join('-') // all elements in a single string
'x-b-c'
> arr.join('')
'xbc'
> arr.join()
'x,b,c'
عناصر پر تکرار کے لئے کئی صف کے طریقے ہیں (دیکھیں تکرار (غیر تباہ کن) ۔ دو اہم ترین فار ایچ اور میپ ہیں۔
forEach ایک صف پر تکرار کرتا ہے اور موجودہ عنصر اور اس کے انڈیکس کو ایک فنکشن کو دیتا ہے:
[ 'a', 'b', 'c' ].forEach(
function (elem, index) { // (1)
console.log(index + '. ' + elem);
});
پچھلا کوڈ مندرجہ ذیل آؤٹ پٹ پیدا کرتا ہے:
0. a
1. b
2. c
نوٹ کریں کہ لائن (1) میں فنکشن کو دلیلوں کو نظر انداز کرنے کی آزادی ہے۔ اس میں ، مثال کے طور پر ، صرف پیرامیٹر عنصر ہوسکتا ہے۔
نقشہ ایک موجودہ صف کے ہر عنصر پر ایک فنکشن کا اطلاق کرکے ایک نیا صف بناتا ہے:
> [1,2,3].map(function (x) { return x*x })
[ 1, 4, 9 ]
جاوا اسکرپٹ میں باقاعدہ اظہار کے لئے بلٹ ان معاونت ہے۔ وہ شگاف کے ساتھ حدود ہیں:
/^abc$/
/[A-Za-z0-9]+/
> /^a+b+$/.test('aaab')
true
> /^a+b+$/.test('aaa')
false
> /a(b+)a/.exec('_abbba_aba_')
[ 'abbba', 'bbb' ]
واپس آنے والی صف میں انڈیکس 0 پر مکمل میچ ، انڈیکس 1 پر پہلے گروپ کی گرفت وغیرہ شامل ہے۔ اس طریقہ کو بار بار استعمال کرنے کا ایک طریقہ ہے (جس پر بحث کی گئی ہے RegExp.prototype.exec: Capture Groups) تمام میچز حاصل کرنے کے لئے۔
> '<a> <bbb>'.replace(/<(.*?)>/g, '[$1]')
'[a] [bbb]'
replace کا پہلا پیرامیٹر ایک /g پرچم کے ساتھ ایک باقاعدہ اظہار ہونا ضروری ہے۔ بصورت دیگر ، صرف پہلی موجودگی کی جگہ لے لی جاتی ہے۔ اس کی جگہ کا حساب لگانے کے لئے فنکشن کا استعمال کرنے کا ایک طریقہ بھی ہے (جیسا کہ String.prototype.replace: Search and Replace میں تبادلہ خیال کیا گیا ہے) ۔
ریاضی ریاضیاتی افعال کے ساتھ ایک اعتراض ہے۔ یہاں کچھ مثالیں ہیں:
> Math.abs(-2)
2
> Math.pow(3, 2) // 3 to the power of 2
9
> Math.max(2, -1, 5)
5
> Math.round(1.9)
2
> Math.PI // pre-defined constant for π
3.141592653589793
> Math.cos(Math.PI) // compute the cosine for 180°
-1