কেন জাভাস্ক্রিপ্টে আর্গুমেন্টস.ক্যালি.ক্যালার সম্পত্তি হ্রাস করা হয়েছিল?


214

কেন arguments.callee.callerজাভাস্ক্রিপ্টে সম্পত্তি হ্রাস করা হয়েছিল?

এটি যুক্ত করা হয়েছিল এবং তার পরে জাভাস্ক্রিপ্টে অবচয় করা হয়েছিল, তবে এটি ECMAScript দ্বারা সম্পূর্ণ বাদ দেওয়া হয়েছিল। কিছু ব্রাউজার (মোজিলা, আইই) সর্বদা এটি সমর্থন করে এবং সমর্থন সরানোর জন্য মানচিত্রে কোনও পরিকল্পনা নেই। অন্যরা (সাফারি, অপেরা) এর জন্য সমর্থন অবলম্বন করেছে, তবে পুরানো ব্রাউজারগুলিতে সমর্থন অবিশ্বাস্য।

এই মূল্যবান কার্যকারিতাটি লম্বায় রাখার কোনও উপযুক্ত কারণ আছে?

(বা অন্যথায়, কলিং ফাংশনটিতে কোনও হ্যান্ডেল দখল করার আরও ভাল উপায় আছে কি?)


2
এটি অন্যান্য ব্রাউজারগুলির দ্বারা সমর্থিত কারণ যে কোনও বৈশিষ্ট্য যা ব্যাপকভাবে ব্যবহারের মডিকাম পায় তা অন্য ব্রাউজারের জন্য একটি সামঞ্জস্যতা বাগ হয়ে যাবে। যদি কোনও সাইট কোনও বৈশিষ্ট্য ব্যবহার করে যা কেবলমাত্র একটি ব্রাউজারে বিদ্যমান থাকে তবে সাইটটি অন্য সকলের মধ্যেই নষ্ট হয়ে যায় এবং সাধারণত ব্যবহারকারীরা মনে করেন যে এটি ব্রাউজারটি নষ্ট হয়ে গেছে।
olliej

4
(প্রায় সমস্ত ব্রাউজারই এটি এক সময় বা অন্য সময়ে এটি করেছে, উদাহরণস্বরূপ, এই বৈশিষ্ট্যটি (এবং নিজেই জেএস) নেটস্কেপ থেকে এসেছে, এক্সএইচআর আইই থেকে উদ্ভূত হয়েছে, সাফারিতে ক্যানভাস ইত্যাদি these এর মধ্যে কিছু কার্যকর রয়েছে এবং অন্যান্য ব্রাউজারগুলি সেগুলি গ্রহণ করেছে) সময়ের সাথে (JS, ক্যানভাস, XHR সব উদাহরণ), কিছু (.callee) নয়।
olliej

@ ওলিজেজ সমর্থন করার বিষয়ে আপনার মন্তব্যটি এটি ব্যবহার করার কারণে এবং এটি মানক না হওয়ার কারণে নয় (বা এমনকি এটি স্ট্যান্ডার্ডে অবমূল্যায়ন করা সত্ত্বেও) খুব সত্য! এ কারণেই আমি যখনই বোধ করি তারা আমাকে সহায়তা করছে না আমি বেশিরভাগ মানদণ্ডকে উপেক্ষা করতে শুরু করি। আমরা বিকাশকারীরা কী কাজ করে না তা অনুমান করে যা আমাদের করা উচিত তা না করে মানদণ্ডের দিকটি গঠন করতে পারি। এই আমরা কিভাবে পেয়েছিলাম <b>এবং <i>ফিরে (হ্যাঁ, ঐ এক পর্যায়ে অবচিত হয়েছে)।
স্টিজন ডি উইট

উত্তর:


252

জাভাস্ক্রিপ্টের প্রারম্ভিক সংস্করণগুলিতে নামযুক্ত ফাংশন এক্সপ্রেশনগুলিকে অনুমতি দেয়নি এবং এর কারণে আমরা একটি পুনরাবৃত্ত ফাংশন প্রকাশ করতে পারি না:

 // This snippet will work:
 function factorial(n) {
     return (!(n>1))? 1 : factorial(n-1)*n;
 }
 [1,2,3,4,5].map(factorial);


 // But this snippet will not:
 [1,2,3,4,5].map(function(n) {
     return (!(n>1))? 1 : /* what goes here? */ (n-1)*n;
 });

এটি পেতে, arguments.calleeযোগ করা হয়েছিল যাতে আমরা করতে পারি:

 [1,2,3,4,5].map(function(n) {
     return (!(n>1))? 1 : arguments.callee(n-1)*n;
 });

তবে এটি আসলে খুব খারাপ সমাধান ছিল কারণ এটি (অন্যান্য যুক্তি, কলি এবং কলার সমস্যাগুলির সাথে একত্রে) ইনলাইনিং এবং লেজ পুনরাবৃত্তি সাধারণ ক্ষেত্রে অসম্ভব করে তোলে (আপনি এটি ট্রেসিং ইত্যাদির মাধ্যমে নির্বাচিত ক্ষেত্রে এটি অর্জন করতে পারেন তবে সেরা কোডও চেকগুলির কারণে সাব অনুকূলতম যা অন্যথায় প্রয়োজনীয় হবে না)। অন্যান্য বড় সমস্যাটি হ'ল পুনরাবৃত্তি কলটি একটি পৃথক thisমান পাবে, উদাহরণস্বরূপ:

var global = this;
var sillyFunction = function (recursed) {
    if (!recursed)
        return arguments.callee(true);
    if (this !== global)
        alert("This is: " + this);
    else
        alert("This is the global");
}
sillyFunction();

যাইহোক, একমাস্ক্রিপ্ট 3 নামযুক্ত ফাংশন এক্সপ্রেশনগুলির অনুমতি দিয়ে এই সমস্যাগুলি সমাধান করেছে, যেমন:

 [1,2,3,4,5].map(function factorial(n) {
     return (!(n>1))? 1 : factorial(n-1)*n;
 });

এর অসংখ্য সুবিধা রয়েছে:

  • ফাংশনটি আপনার কোডের অভ্যন্তর থেকে অন্য যেকোন মত কল করা যেতে পারে।

  • এটি নামস্থান দূষিত করে না।

  • মান thisপরিবর্তন হয় না।

  • এটি আরও পারফরম্যান্ট ( আর্গুমেন্ট অবজেক্টে অ্যাক্সেস ব্যয়বহুল)।

ওহো,

কেবল উপলব্ধি হয়ে গেছে যে অন্য সমস্ত কিছুর পাশাপাশি প্রশ্নটি arguments.callee.callerবা আরও সুনির্দিষ্টভাবে ছিল Function.caller

যেকোন সময় আপনি স্ট্যাকের যে কোনও ফাংশনের গভীরতম কলার খুঁজে পেতে পারেন এবং আমি উপরে যেমন বলেছি, কল স্ট্যাকের দিকে তাকানোর একটি একক বড় প্রভাব রয়েছে: এটি প্রচুর সংখ্যক অপটিমাইজেশনকে অসম্ভব বা আরও অনেক কঠিন করে তোলে।

যেমন। যদি আমরা গ্যারান্টি দিতে পারি না যে কোনও ফাংশন fকোনও অজানা ফাংশন কল করবে না, তবে ইনলাইন করা সম্ভব নয় f। মূলত এর অর্থ হ'ল যে কোনও কল সাইট যা তুচ্ছভাবে অন্তর্নিহিতভাবে অন্তর্ভুক্ত হতে পারে সেগুলি প্রচুর পরিমাণে রক্ষক সংগ্রহ করে, নিন:

 function f(a, b, c, d, e) { return a ? b * c : d * e; }

যদি জেএস ইন্টারপ্রেটার গ্যারান্টি দিতে না পারে যে সমস্ত প্রদত্ত আর্গুমেন্ট কল করা হয়েছে এমন বিন্দুতে নম্বর, তবে এটি হয় ইনলাইনড কোডের আগে সমস্ত আর্গুমেন্টের জন্য চেক সন্নিবেশ করা প্রয়োজন, অথবা এটি ফাংশনটি ইনলাইন করতে পারে না।

এখন এই বিশেষ ক্ষেত্রে একজন স্মার্ট দোভাষীকে চেকগুলি আরও অনুকূল হতে পুনরায় সাজানো এবং এমন কোনও মান ব্যবহার করা যাচাই করে না যাচাই করে নেওয়া উচিত। তবে অনেক ক্ষেত্রে এটি ঠিক সম্ভব নয় এবং তাই লাইন করা অসম্ভব হয়ে পড়ে।


12
আপনি কি বলছেন যে এটির চিত্রিত করা হয়েছে কারণ এটি অনুকূলিত করা শক্ত? এটুকু মূর্খ।
থমাস এডিং

11
না, আমি বেশ কয়েকটি কারণ তালিকাভুক্ত করেছি, এটি অপ্টিমাইজ করা শক্ত করে তোলে (যদিও সাধারণ ইতিহাসে দেখা গেছে যে জিনিসগুলি অনুকূলকরণ করা শক্ত তাও শব্দার্থবিজ্ঞান রয়েছে যা লোকেরা অনুসরণ করতে অসুবিধা বোধ করে)
লিজে ২

17
এই যুক্তি একটি বিট কৃত্রিম এর মান যদি এটা গুরুত্বপূর্ণ কল দ্বারা নির্ধারণ করা যাবে হয়। সাধারণত এটি ব্যবহার করা হয় না (কমপক্ষে, পুনরাবৃত্ত ফাংশনে এটি নিয়ে আমার কোনও সমস্যা হয়নি)। নাম ধরে ফাংশনটি কল করার একই সমস্যা রয়েছে thisতাই আমি মনে করি এটি কলি ভাল বা খারাপ কিনা সে বিষয়ে এটি অপ্রাসঙ্গিক । এছাড়াও, কলি এবং কলার কঠোর মোডে কেবল "অবচয়" (ECMAscript এড 5, ডিসেম্বর ২০০৯), তবে আমার ধারণা যে ২০০oll সালে অলিজে পোস্ট করার পরে এটি জানা ছিল না।
রবজি

8
) আমি এখনও যুক্তি দেখতে পাচ্ছি না। প্রথম শ্রেণির ফাংশনগুলির সাথে যে কোনও ভাষায়, কোনও ফাংশন বডি সংজ্ঞায়িত করতে সক্ষম হওয়ার স্পষ্ট মূল্য রয়েছে যা আমি না জেনে নিজেকে উল্লেখ করতে পারি
মার্ক রেড

8
রবজি এটি উল্লেখ করেছে, তবে আমি মনে করি না যে এটি সমস্ত পরিষ্কার ছিল: একটি নামযুক্ত ফাংশন ব্যবহার করে পুনরাবৃত্তি করা কেবলমাত্র বিশ্বব্যাপী সুযোগ thisথাকলে এর মান সংরক্ষণ করবে this। অন্যান্য সমস্ত ক্ষেত্রে, প্রথম পুনরাবৃত্তির কলের পরে মানটির পরিবর্তন this হবে , তাই আমি মনে করি আপনার উত্তরগুলির অংশগুলি সংরক্ষণের জন্য ইঙ্গিত করে যা thisসত্যই বৈধ নয়।
JLRishe

89

arguments.callee.callerযদিও এটি সম্পত্তি ব্যবহার করে তবে তা অবহেলা করা হয় না । ( কেবলমাত্র আপনাকে বর্তমান ফাংশনটির জন্য একটি রেফারেন্স দেবে)Function.callerarguments.callee

  • Function.callerযদিও ইসিএমএ 3 অনুসারে অ-মানক, সমস্ত বর্তমান প্রধান ব্রাউজারগুলিতে প্রয়োগ করা হয় ।
  • arguments.caller এর পক্ষে অবচয় করা হয়েছে এবং বর্তমান কয়েকটি বড় ব্রাউজারগুলিতে প্রয়োগ করা হয়নি (যেমন ফায়ারফক্স 3)।Function.caller

তাই পরিস্থিতি আদর্শ চেয়ে কম হয়, কিন্তু আপনি সমস্ত প্রধান ব্রাউজারগুলি জুড়ে জাভাস্ক্রিপ্ট কলিং ফাংশন অ্যাক্সেস করতে চান, আপনি ব্যবহার করতে পারেন , অথবা মাধ্যমে একটি বেনামী ফাংশন মধ্যে থেকে সম্পত্তি, হয় একটি নামে ফাংশন রেফারেন্স সরাসরি অ্যাক্সেস সম্পত্তি।Function.callerarguments.callee


5
এটি হ'ল যা অত্যন্ত মূল্যবান এবং হ্রাসযোগ্য নয় তার সর্বোত্তম ব্যাখ্যা। ফাংশন.ক্যালার কী করতে পারে না তার একটি উদাহরণের জন্য (পুনরাবৃত্ত ফাংশনগুলির স্ট্যাক ট্রেস পান), বিকাশকারী.মোজিলা.আর.ইন
জুয়ান মেন্ডেস

1
যদিও, arguments.calleeকঠোর মোডে নিষিদ্ধ। এটি আমাকেও দু: খিত করেছে, তবে এটি আর ব্যবহার না করাই ভাল।
গ্রাস ডাবল

1
আপনার MDX- তে থাকা আর্গুমেন্টস ক্যালির হাইপারলিঙ্কটি বলে যে এটি কঠোর মোডে সরানো হয়েছে। এটা কি অবমূল্যায়নের মতো নয়?
স্টাইলফেল

1
নোট যেটি arguments.callee.callerES5 কঠোর মোডে অবচিত করা হয়েছে: "আরেকটি বৈশিষ্ট্য যা অবহেলা করা হয়েছিল তা ছিল আর্গুমেন্টস.ক্যালি ক্যালার, বা আরও বিশেষত ফাংশন.ক্যালার" " ( উত্স )
thdoan

29

যুক্তিযুক্ত কলির চেয়ে নামযুক্ত ফাংশনগুলি ব্যবহার করা ভাল :

 function foo () {
     ... foo() ...
 }

বেশী ভালো

 function () {
     ... arguments.callee() ...
 }

নামকরণ করা ফাংশনটিতে কলার সম্পত্তিটির মাধ্যমে এর কলারে অ্যাক্সেস থাকবে :

 function foo () {
     alert(foo.caller);
 }

যা চেয়ে ভাল

 function foo () {
     alert(arguments.callee.caller);
 }

অবচয় হ্রাস বর্তমান ECMAScript নকশা নীতিগুলির কারণে ।


2
নামযুক্ত ফাংশনটি কেন ব্যবহার করা ভাল তা আপনি বর্ণনা করতে পারেন। বেনামে ফাংশনে কখনই কলি ব্যবহার করার দরকার নেই?
অ্যান্টনিডব্লু জোন্স

27
আপনি যদি কোনও বেনামি ফাংশনে কলি ব্যবহার করছেন, তবে আপনার একটি ফাংশন রয়েছে যা বেনামি হওয়া উচিত নয়।
Prestaul

3
কখনও কখনও ডিবাগ করার সহজতম উপায় হ'ল কলার () দিয়ে। এই জাতীয় ক্ষেত্রে ফাংশনগুলি সাহায্য করবে না - আপনি কোন ফাংশনটি কল করছেন তা কার্যকর করার চেষ্টা করছেন।
স্যামগুডি

6
আরও ভাল সংজ্ঞা দিন। উদাহরণস্বরূপ, আই 6 8-8 ফাংশন কিরিক্সের নাম দিয়েছে যখন আর্গুমেন্ট.ক্যালি কাজ করে।
সেএমসি

1
আই 6 88 কুইর্কস বাদে, এটি কোডকে শক্ত করে মিলিয়ে তোলে। যদি অবজেক্টস এবং / অথবা ফাংশনগুলির নামগুলি হার্ডকোড করা থাকে, তবে আরডাসড এবং আরএসকে 82 হিসাবে উল্লেখ করা হয়েছে বড় রিফ্যাক্টরিং বিপদ রয়েছে, যা কেবলমাত্র কোড বেসের আকার বাড়ার সাথে সাথে বৃদ্ধি পায়। ইউনিট পরীক্ষাগুলি প্রতিরক্ষার একটি লাইন, এবং আমি সেগুলি ব্যবহার করি, তবে তারা এখনও এমন কোনও উত্তর নয় যা সত্যই আমাকে এই হার্ডকোডিংয়ের বিষয়ে ব্যক্তিগতভাবে ব্যঙ্গ করে।
জুঁই হেগম্যান

0

শুধু একটি এক্সটেনশন। "এই" এর মান পুনরাবৃত্তির সময় পরিবর্তন হয়। নিম্নলিখিত (সংশোধিত) উদাহরণে, ফ্যাক্টরিয়ালটি {foo: সত্য} অবজেক্ট পায়।

[1,2,3,4,5].map(function factorial(n) {
  console.log(this);
  return (!(n>1))? 1 : factorial(n-1)*n;
},     {foo:true}     );

প্রথমবার বলা ফ্যাক্টরিয়ালটি বস্তুটি পায়, তবে এটি পুনরাবৃত্ত কলগুলির জন্য সত্য নয়।


1
কারণ আপনি এটি ভুল করছেন। যদি thisরক্ষণাবেক্ষণের প্রয়োজন হয় তবে লিখুন factorial.call(this, n-1)আমি আসলে পুনরাবৃত্তির কোড লেখার সন্ধান পেয়েছি, সাধারণত কোনও গাছে নেই this, বা thisকোনও নোডকে বোঝায় এবং আসলে এটির পরিবর্তন হয় এটি ভাল।
স্টিজন ডি উইট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.