PDA

View Full Version : سوال: معنی Function.prototype.call()



Hussain<ELite>
شنبه 15 مهر 1391, 19:10 عصر
سلام
تو methodبرای تابع ها داریم یکی call() هست و دیگری apply() میخواستم کارکرد و کاربرد این دو تا را بدانم.
البته مستندات رو میخونم ولی گیج کننده است و متوجه نمیشوم برای چه باید همچین کاری کرد!
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/call
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

Variable
یک شنبه 16 مهر 1391, 18:39 عصر
شما یک کلاس دارید . به نام دانشجو . این کلاس یک متد داره به نام مثلا "چاپ نام" .
خب حالا شما یک کلاس دیگه داری به نام اساتید . شما میتونی یه متد برای این کلاس به سازی به نام "چاپ نام " یا نه میتونی برای اینکه از دوباره نویسی جلو گیری کنی . ازمتد مربوط به کلاس دانشجو استفاده کنی. برای اینکار شما به متد مربوط به کلاس دانشجو میگی . که عملیات خودش رو روی کلاس دیگه ایی به نام اساتید انجام بده .
و فرق این دو متدcall , apply در ارسال پارامتر به اون هاست . که در یکی باید پارامتر ها رو تک تک بفرستی . و در دیگری میتونی پارامتر ها رو به صورت ارایه بفرستی .

Hussain<ELite>
یک شنبه 16 مهر 1391, 20:54 عصر
ممنون متوجه شدم. ولی خب مثلا override اینجا چه کاره هست؟ یعنی نمی تونستیم یک کلاس چاپ درست کنیم و از متودهای اون کلاس استفاده کنیم تا اینکار؟ یا یا override یا static

eAmin
یک شنبه 16 مهر 1391, 22:28 عصر
یکی از مهمترین و در واقع میشه گفت یکی از بهترین امکانات JavaScript در این هست که به برنامه نویس اجازه میده تا تابع های خودش رو در context های مختلف صدا بزنه. مثلا وقتی شما دارید با اشاره گر this به یک شئ یا متغییر مورد نظر اشاره میکنید ممکنه در حین فرخوانی در یک context دیگه که مربوط به یک تابع دیگه هست و اونطور که شما انتظار داشتید عمل نکنه و جواب نادرست به شما بده یا به شئ دیگری شاره کنه. اینجاست که کاربرد واقعی call و apply مشخص میشه. در واقع شما با این دو متد context تابع خودتون رو "هر طور که بخواید تعیین میکنید/به هر شئ ای که بخواید ربط میدید".
این یک مثال که گویای همه چیز هست:


var c = 'cccccc';
var a = (function() {
function b() {
console.log(this.c);
}

return {
c: 'dddddd',
p: function() {
b(); // print 'cccccc'
b.call(this); // print 'dddddd'
}
};
}());

a.p();

تابع b برای بار اول که اجرا میشه، چون در تابع a ایجاد شده پس به context تابع a اشاره میکنه (*دقت کنید به خود a اشاره نمیکنه) و this در اینجا یعنی global یعنی به تمام آبجکتها global دسترسی داره.
وقتی تابع رو برای بار دوم اجرا میکنیم با توجه به اینکه context اون در متد p تغییر داده شده پس به آبجکتی اشاره میکنه که p در اون محیط ایجاد شده.

* اما وقتی call/apply رو به اینصورت استفاده کنید کلمه this دقیقا به خود a اشاره میکنه.

function a(args) {
obj.apply(this, args);
}

Variable
یک شنبه 16 مهر 1391, 22:57 عصر
ممنون متوجه شدم. ولی خب مثلا override اینجا چه کاره هست؟ یعنی نمی تونستیم یک کلاس چاپ درست کنیم و از متودهای اون کلاس استفاده کنیم تا اینکار؟ یا یا override یا static
شما یک متددارید که مخصوص یک کلاس هست.
حالا شما یا باید این متد رو کلن کپی کنی و برای یک کلاس دیگت بکار ببری یا اینکه از متد های کال و اپلای استفاده کنی. البته در جاوااسکریپت مفهومی به نام کلاس وجودنداره . هر چی هست شئی هست .

eAmin
دوشنبه 17 مهر 1391, 00:09 صبح
شما یک کلاس دارید . به نام دانشجو . این کلاس یک متد داره به نام مثلا "چاپ نام" .
خب حالا شما یک کلاس دیگه داری به نام اساتید . شما میتونی یه متد برای این کلاس به سازی به نام "چاپ نام " یا نه میتونی برای اینکه از دوباره نویسی جلو گیری کنی . ازمتد مربوط به کلاس دانشجو استفاده کنی. برای اینکار شما به متد مربوط به کلاس دانشجو میگی . که عملیات خودش رو روی کلاس دیگه ایی به نام اساتید انجام بده .

شما یک متددارید که مخصوص یک کلاس هست.
حالا شما یا باید این متد رو کلن کپی کنی و برای یک کلاس دیگت بکار ببری یا اینکه از متد های کال و اپلای استفاده کنی.

مثال شما خیلی برای اینکه کاربرد call/apply رو بیان کنید مناسب نیست. اونطور که من از حرفهای شما برداشت کردم خیلی راحت میتونیم با تکه کد زیر نتیجه دلخواهمون برسیم و در اینجا متوجه استفاده از call نمیشم، اگر ممکنه یک مثال عملی بزنید:

var Student = function() {};
Student.prototype.printName = function(name) {
console.log(name);
}

var Professor = function() {};
Professor.prototype = new Student();

var f = new Professor();
f.printName('eAmin');

// change context example

var Student = function() {};
Student.prototype.name = 'Student';
Student.prototype.printName = function() {
console.log(this.name);
}

var Professor = function() {};
Professor.prototype = new Student();
Professor.prototype.name = 'Professor';

var f = new Professor();
f.printName(); // Professor
f.printName.call(new Student()); // Student

Variable
دوشنبه 17 مهر 1391, 00:45 صبح
بله اشتباه کردم
منظورمن توپست اول دقیقا این بود :
با فرض اینکه ما دو شی کاملا جدا از هم داریم . و برای اینکه کد نویسی کمتری داشته باشیم (فارق از مباحث ابجکت اورینتد)

var stud={
name:'var',
printName:function(){
console.log(this.name);
}
}

var prof={
name:'myprof'
}

stud.printName.call(prof);
یا این
var stud=function(){
this.name='myStud';
this.printName=function(){
console.log(this.name);
}
}

var prof=function(){
this.name='myprof'
}

var s=new stud();
var p=new prof();

s.printName.call(p);


و در پست دوم هم در جواب اینکه از اوورراید کردن چرا استفاده نمیشه . چون فرض کردم دو شی جدا از هم هستند . نه یک شی والد و فرزند.
.و فقط منظورم رسوندن کاربرد کال و اپلای بود.