آموزش جاوا اسکریپت Java Script قسمت ششم

اکرم کریمی 1395/4/17 886

با سلام خدمت همه دنبال کنندگان آموزشهای گروه برنامه نویسان

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

جلسه پیش مختصری در مورد Inspector توضیح دادیم با اینکه بعضی از قسمتهاش باقی موند اما برای اینکه از کدنویسی زیاد دور نشیم به ادامه مثالمون در جلسه چهارم برمی گردیم. سعی میکنم قسمتهایی از inspector که گفته نشد رو در لابلای آموزش خدمتتون ارائه بدم.

و اما ادامه مثال StopWatch؛ تا اینجا پیش رفته بودیم که دو دکمه start و stop داشتیم اما فقط برای دکمه start رویداد نوشتیم، حالا میخوایم برای دکمه stop رویداد بنویسیم. (با عرض پوزش مجبورم که یه سری مفاهیم رو هم در آموزشم جا بدم)

من از تابع setInterval استفاده کردم، این تابع یک مقدار number به عنوان خروجی به من میده که شناسه این تابع است. من بعدا به وسیله این شناسه میتونم این Interval رو از بین ببرم. که در حقیقت عملیاتی است که من باید در رویداد کلیک دکمه stop انجام بدم. خب برای اینکار یه متغیر سراسری تعریف میکنم به اسم myInterval. کد رو به صورت کامل براتون قرار میدم و بعد روی کد توضیحات لازم رو میدم.

کدهای HTML:

<div id="demo">0</div>
<input type="button" value="start" onclick="start()" />
<input type="button" value="stop" onclick="stop()" />

 

                 

 

کدهای جاوااسکریپت:

'use strict';
var s = 0;
var myInterval;
function start() {
 myInterval = setInterval(function () { document.querySelector("#demo").innerText = ++s; }, 1000);
}
function stop() {
 clearInterval(myInterval);
}

من یه تابع با نام stop() ایجاد کردم که در بدنه آن، تابع clearInterval رو فراخوانی کردم. ورودی این تابع شناسه ایه که تابع setInterval به من برمیگردونه. تابع stop() رو در رویداد onclick دکمه stop فراخوانی کردم.

clearInterval با استفاده از شناسه Interval، Interval مورد نظر رو پاک میکنه و از بین میبره. هر زمان که شما این ساعت رو stop کنید و مجددا start کنید شناسه Interval یکی بهش اضافه میشه. میتونید مقدار این شناسه رو با قرار دادن debugger در بدنه تابع start و add to watch کردن متغیر myInterval ملاحظه کنید. البته ما با این شناسه کاری نداریم به غیر از اینکه برای فراخوانی تابع clearInterval ازش استفاده کنیم.

ببخشید ترتیب عبارت به هم خورد، مجددا عبارت رو قرار میدم

در اینجا clearInterval با استفاده از شناسه Interval، Interval مورد نظر رو پاک میکنه و از بین میبره. هر زمان که شما این ساعت رو stop کنید و مجددا start کنید شناسه Interval یکی بهش اضافه میشه. میتونید مقدار این شناسه رو با قرار دادن debugger در بدنه تابع start و add to watch کردن متغیر myInterval ملاحظه کنید. البته ما با این شناسه کاری نداریم به غیر از اینکه برای فراخوانی تابع clearInterval ازش استفاده کنیم.

حالا میخوام در مورد محدوده عملکرد متغیرها یه توضیحی بدم. توی جاوااسکریپت هر جفت آکلاد باز و بسته { } یک بلاک رو تشکیل میده و حوزه ای که یک متغیر میتونه صدا زده شود در بلاکی است که اون متغیر تعریف میشه و خارج از اون بلاک شما نمیتونید اون متغیر رو صدا بزنید. که به اصطلاح میگن متغیر محلی اون بلاک. حالا ما اگر این متغیر رو به صورت مستقیم در بدنه اصلی script یا فایل js تعریف کنیم بهش میگیم متغیر سراسری یا global. که از همه جای فایل HTML میتونیم بهش دسترسی داشته باشیم (البته در خط کدهایی که بعد از تعریف متغیر مربوطه نوشته می شوند). ما میتونیم یک متغیر سراسری هم در یک کلاس تعریف کنیم اما محدوده عملکرد اون متغیر به همان کلاس محدود میشه و خارج از اون کلاس دیگر ما به آن متغیر دسترسی نداریم.

متغیرهای s و myInterval که من در این مثال در بدنه اصلی فایل تعریف کردم متغیرهای سراسری من هستند. به همین دلیل من میتونم توی توابع دیگرم بهشون دسترسی داشته باشم. حالا اگر من مثلا متغیر myInterval رو در داخل تابع start تعریف میکردم دیگه توی تابع stop بهش دسترسی نداشتم که از بینش ببرم. ممکنه بپرسید که من متغیر s رو فقط توی تابع start ازش استفاده کردم، پس چرا اون رو به صورت محلی در تابع start ایجاد نکردم و به صورت سراسری تعریفش کردم؛ دلیل اینکار اینه که من میخواستم بعد از اینکه ساعت من مشغول به کار شد و من یکبار دکمه stop رو بزنم و بعد دوباره دکمه start رو بزنم متغیر s مقدار قبلی خودش رو حفظ کنه و گرنه ساعت من reset میشد. میتونید اینکار رو امتحان کنید و متغیر s رو در داخل تابع start تعریف کنید.

'use strict';
var myInterval;
function start() {
 var s = 0;
 myInterval = setInterval(function () { document.querySelector("#demo").innerText = ++s; }, 1000);
}
function stop() {
 clearInterval(myInterval);
}

بعد از اینکه جابجاش کردید دیدید که با کلیک مجدد دکمه start ساعت من reset میشه.

حالا اگر که من دو متغیر هم نام محلی و سراسری داشته باشم و بخوام یکیشون رو صدا بزنم، کدوم یکی صدا زده خواهد شد؟ مثلا در همین کد بالا من متغیر s رو با مقدار 10 به صورت سراسری تعریف میکنم. حالا توی تابع start بعد از تعریف متغیر محلی s میخوام از s استفاده کنم و مقدارش رو ببینم، گفتیم که با add to watch من میتونم مقدار یک متغیر رو ببینم یا اینکه میتونم در Inspector به تب console برم و s رو تایپ کنم و دکمه enter رو بزنم تا مقدار این متغیر رو در لحظه ای که در حال اجرای کدهای درون تابع start هستم ببینم. خواهم دید که مقدار این متغیر 0 است، یعنی مقدار متغیر محلی ام. پس اولویت با متغیر محلی است.

var s = 10;
function start() {
 var s = 0;
 debugger; // add to watch s
 myInterval = setInterval(function () { document.querySelector("#demo").innerText = ++s; }, 1000);
}

شئ document:

اینجا لازمه من اشاره ای به BOM و DOM داشته باشم.

DOM: Document Object Model

DOM تمام عناصر موجود در یک صفحه وب را به صورت درختی از گره ها (node) نمایش می دهد و با استفاده از آن میتونید به راحتی گره ها را حذف، اضافه و یا جابجا کنید.

BOM: Browser Object Model

از BOM برای دسترسی و دستکاری ویژگی های پنجره یک مرورگر می توان استفاده کرد؛ با استفاده از آن میتوان کارهایی مثل باز کردن پنجره های Popup، تغییر اندازه پنجره، جابجایی و یا بستن آنها و ... انجام داد.

در جاوااسکریپت، document یک شئ است که به سند html شما اشاره دارد (به تگ html). این شئ دارای یک سری خصوصیات مانند URL و همچنین دارای یکسری خصوصیات مجموعه ای برای دسترسی به انواع عناصر داخل صفحه است مانند anchors، forms، images و .... به هر یک از اشیاء درون این مجموعه ها میتوانید از طریق اندیس یا نام آنها دسترسی داشته باشید.

همچنین شئ document دارای متدهایی از جمله write و سلکتورهایی که در جلسه چهارم گفتیم نیز می باشد.

شئ document تنها شئ مشترک بین DOM و BOM است

تعریف تابع: شکل کلی تعریف تابع در جاوااسکریپت به صورت زیر است:

function [function name] ([param1, param2, …]) {
// body of function
}

 

تابع میتواند دارای خروجی باشد یا اینکه دارای هیچ خروجی نباشد. ورودی های تابع میتواند انواع مختلف داده و یا حتی تابع باشد. مانند تابع setInterval که ورودی اول آن یک تابع است.

 

در هنگام فراخوانی یک تابع، در صورتی که تعداد آرگومانها در فراخوانی تابع، با تعداد پارامترهای ورودی در تابع برابر نباشد، با هیچ خطایی از سمت جاوااسکریپت بر نخواهید خورد

function myFunc(param1, param2) {
//
}
myFunc(); // it’s correct

ما میتونیم انواع مختلف خروجی رو در یک تابع داشته باشیم

function myFunc(param1) {
 if (param1 == 1) return true;
 else return “param1 is not valid”;
}

 

در مثال بالا یک خروجی از نوع boolean داریم و یک خروجی از نوع string

 

برگردیم سر مثالمون، حالا من میخوام همون ابتدا که صفحه ام باز میشه stopWatch من هم شروع به حرکت کنه، برای اینکار فقط کافیه تابع start() رو در بدنه اصلی فایل فراخوانی کنم

'use strict';
var s = 0;
var myInterval;
start();
function start() {
 myInterval = setInterval(function () { document.querySelector("#demo").innerText = ++s; }, 1000);
}
function stop() {
 clearInterval(myInterval);
}

 

در این مثال چون حجم صفحه زیاد نیست و همچنین تابع ورودی setInterval یک ثانیه بعد فراخوانی میشه من به مشکلی برنمیخورم. اما در صورتی که حجم صفحه بالا باشه قطعا به خطا برمیخورم. چرا؟ چون فایل js من در head صفحه html قرار داره و ابتدا کدهای جاوااسکریپ اجر میشه و بعد المنتهای درون صفحه لود میشن.

 

من دستور

document.querySelector("#demo").innerText

رو فراخوانی کردم، اما هنوز المنتی با این نام درون صفحه قرار نگرفته، پس به من null برمیگردونه و چون نمیتونه برای null خصوصیتی با نام innerText قائل شه کد من به خطا خواهد خورد. برای جلوگیری از این خطا کدهای خودم رو در هنگامی که صفحه به صورت کامل لود میشه فراخوانی میکنم

کد html:

<body onload="showTime()">
 <div id="demo">0</div>
 <input type="button" value="start" onclick="start()" />
 <input type="button" value="stop" onclick="stop()" />
</body>

کد js:

'use strict';
var s = 0;
var myInterval;
function onload() {
 start();
}

function start() {
 myInterval = setInterval(function () { document.querySelector("#demo").innerText = ++s; }, 1000);

}

function stop() {
 clearInterval(myInterval);
}

کد html رو اصلاح میکنم

<body onload="onload()">
 <div id="demo">0</div>
 <input type="button" value="start" onclick="start()" />
 <input type="button" value="stop" onclick="stop()" />
</body>

 

نکته ای که در اینجا باید بهش اشاره کنم اینه که اگر شما تابع start و stop را در تابع onload تعریف کنید دیگر در رویداد کلیک دکمه های مربوطه قادر به پیدا کردن آنها نیست. پس نمیشه تابعی که به عنوان رویداد تعریف شده و در المنتهای html فراخوانی شده را در درون تابع دیگری قرار داد

 

دوستان در جلسه بعد به eventlistener و callback function خواهیم پرداخت.

دانلود PDF قسمت ششم آموزش جاوااسکریپ

قسمت بعدی قسمت قبلی