আমি কি কোনও জাভাস্ক্রিপ্ট ফাংশনটির নাম দিতে পারি এবং তাৎক্ষণিকভাবে এটি সম্পাদন করতে পারি?


90

আমার এর মধ্যে বেশ কয়েকটি রয়েছে:

function addEventsAndStuff() {
  // bla bla
}
addEventsAndStuff();

function sendStuffToServer() {
  // send stuff
  // get HTML in response
  // replace DOM
  // add events:
  addEventsAndStuff();
}

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

এই সেট আপ (বা আছে?) এর সাথে কোনও ভুল নেই, তবে আমি কি এটি কিছুটা মসৃণ করতে পারি? আমি addEventsAndStuff()ফাংশনটি তৈরি করতে এবং তাৎক্ষণিকভাবে ফোন করতে চাই, সুতরাং এটি এত অপেশাদার মনে হয় না।

নিম্নলিখিত উভয়ই একটি সিনট্যাক্স ত্রুটির সাথে সাড়া দেয়:

function addEventsAndStuff() {
  alert('oele');
}();

(function addEventsAndStuff() {
  alert('oele');
})();

কোনো সেবার?



4
না, @ ক্রিশ্চিয়ানসানচেজ
ম্যাক্সিমা আলেক্জ

ইমো আপনার দ্বিতীয় কোড ব্লক পড়া কঠিন। প্রথম কোড ব্লকে এটি প্রতিটি পাঠকের পক্ষে স্পষ্ট, আপনি init এর পরে ফাংশনটি কল করেন। পাঠকদের শেষে বন্ধ এবং ওভারড্রেড বন্ধনীগুলি উপেক্ষা করার প্রবণতা রয়েছে।
কায়সার

উত্তর:


123

আপনি আপনার প্রশ্নে যে উদাহরণটি পোস্ট করেছেন তাতে কোনও ভুল নেই .. এটি করার অন্য উপায়টি অদ্ভুত লাগতে পারে তবে:

var addEventsAndStuff;
(addEventsAndStuff = function(){
    // add events, and ... stuff
})();

জাভাস্ক্রিপ্টে কোনও ফাংশন সংজ্ঞায়িত করার দুটি উপায় রয়েছে। একটি কার্য ঘোষণা:

function foo(){ ... }

এবং একটি ফাংশন এক্সপ্রেশন, যা উপরোক্ত ব্যতীত কোনও ফাংশন সংজ্ঞায়নের কোনও উপায়:

var foo = function(){};
(function(){})();
var foo = {bar : function(){}};

... ইত্যাদি

ফাংশন এক্সপ্রেশন নাম দেওয়া যেতে পারে, তবে তাদের নাম ধারণ স্কোপ প্রচার করা হয় না। অর্থ এই কোডটি বৈধ:

(function foo(){
   foo(); // recursion for some reason
}());

তবে এটি নয়:

(function foo(){
    ...
}());
foo(); // foo does not exist

সুতরাং আপনার ফাংশনটির নাম দেওয়ার জন্য এবং তাৎক্ষণিকভাবে এটিকে কল করার জন্য আপনাকে একটি স্থানীয় ভেরিয়েবল সংজ্ঞায়িত করতে হবে, আপনার ফাংশনটিকে একটি এক্সপ্রেশন হিসাবে নির্ধারণ করুন, তারপরে এটি কল করুন।


4
"ফাংশন এক্সপ্রেশনগুলির নাম দেওয়া যেতে পারে" নামযুক্ত ফাংশন এক্সপ্রেশন থেকে সাবধান। আপনার বর্ণনা অনুসারে তাদের কাজ করা উচিত , তবে তারা IE9 এর আগে IE এ নয় - আপনি দুটি ফাংশন পান এবং ফাংশনের নাম ফাঁস হয়। বিশদ: kangax.github.com/nfe (এটি শেষ পর্যন্ত আই 9 এ স্থির করা হয়েছে))
টিজে ক্রোডার

@ টিজে - রেফারেন্সের জন্য ধন্যবাদ। আমি বুঝতে পারি নি যে আমি কখনই চূড়ান্ত পণ্য পরীক্ষা না করে আইআই ব্যবহার করি না :) আমি ধরে নিচ্ছি যে আইই 9 আই 7/8 মোডে সেট করার সময় এই বাগটি অনুকরণ করে না? আমি মনে করি এটি এখনও আই 9 জেএস ইঞ্জিন ব্যবহার করে ... মেহ
মার্ক কান

তাহলে আমাকে মতো, আপনি jshint সমস্যায় এই পদ্ধতিতে চালানোর জন্য, আপনি ব্যবহার করতে পারেন call(): এখান থেকে পদ্ধতি stackoverflow.com/a/12359154/1231001
cfx

এই পদ্ধতির নির্দিষ্ট পরিস্থিতিতে দরকারী মনে হতে পারে, তবে পড়তে কিছুটা কঠিন হওয়ার পাশাপাশি এটি ভার্চুয়ালি একই পরিমাণ পাঠ্য বলে মনে হচ্ছে।
ভ্লাদিমির

16

এটির জন্য একটি ভাল শর্টহ্যান্ড রয়েছে (কোনও ক্রিয়াটি বরাদ্দকরণের জন্য কোনও ভেরিয়েবলগুলি ঘোষণার প্রয়োজন নেই):

var func = (function f(a) { console.log(a); return f; })('Blammo')

কোনটি rফাংশন ফিরে আসবে? function rবা var r? উৎসুক. ভাল সমাধান। যদিও একটি লোক হবে না =)
রুডি

আমি এটি আরো স্পষ্ট করা নতুন নামকরণ করেছি, কিন্তু return rহত function rযেমন যে এটা সুযোগ ছিল। রেকর্ডিং স্কালায় তাই স্থায়ীভাবে অনলাইনে কিছু পাওয়ার চেষ্টা করা হচ্ছে।
জেমস গরি ১৩

@ জেমসগরি, ব্রিলিয়ান্ট শর্টহ্যান্ড যাইহোক, আমি কনসোলে দু'বার চেষ্টা করেছি, এটি ফানক, ফানক (), ফানক () () সমস্ত ফ () এর রিটার্ন ফাংশন ডিক্লারেশন বলে মনে হচ্ছে, তবে আমরা ফ্যানক () দ্বারা প্রত্যাশা অনুযায়ী 'ব্লেমো' আউটপুট দিতে পারি? :)?
মাইক 652638

@ মাইক 652638 আমি এটি আমার কনসোলে চালিয়েছি এবং এটি ব্লগম লগ কনসোল করে?
জেমস

5

এই সেট আপ (বা আছে?) এর সাথে কোনও ভুল নেই, তবে আমি কি এটি কিছুটা মসৃণ করতে পারি?

পরিবর্তে ইভেন্ট প্রতিনিধি ব্যবহার দেখুন। ঠিক সেখানেই আপনি ইভেন্টটি এমন কোনও ধারকটিতে দেখেন যা চলে না যা যায় না, এবং তারপরে ইভেন্টটি কোথায় ঘটেছে তা নির্ধারণ করতে এবং সঠিকভাবে এটি পরিচালনা করতে event.target(বা event.srcElementআইই তে) ব্যবহার করুন।

এইভাবে, আপনি কেবলমাত্র একবার হ্যান্ডলার (গুলি) সংযুক্ত করেন এবং আপনি সামগ্রী সরিয়ে নেওয়ার পরেও তারা কাজ চালিয়ে যান।

কোনও সহায়তা সহায়ককে ব্যবহার না করে ইভেন্ট প্রতিনিধি দলের উদাহরণ এখানে রয়েছে:

(function() {
  var handlers = {};

  if (document.body.addEventListener) {
    document.body.addEventListener('click', handleBodyClick, false);
  }
  else if (document.body.attachEvent) {
    document.body.attachEvent('onclick', handleBodyClick);
  }
  else {
    document.body.onclick = handleBodyClick;
  }

  handlers.button1 = function() {
    display("Button One clicked");
    return false;
  };
  handlers.button2 = function() {
    display("Button Two clicked");
    return false;
  };
  handlers.outerDiv = function() {
    display("Outer div clicked");
    return false;
  };
  handlers.innerDiv1 = function() {
    display("Inner div 1 clicked, not cancelling event");
  };
  handlers.innerDiv2 = function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  };

  function handleBodyClick(event) {
    var target, handler;

    event = event || window.event;
    target = event.target || event.srcElement;

    while (target && target !== this) {
      if (target.id) {
        handler = handlers[target.id];
        if (handler) {
          if (handler.call(this, event) === false) {
            if (event.preventDefault) {
              event.preventDefault();
            }
            return false;
          }
        }
      }
      else if (target.tagName === "P") {
        display("You clicked the message '" + target.innerHTML + "'");
      }
      target = target.parentNode;
    }
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = msg;
    document.body.appendChild(p);
  }

})();

সরাসরি উদাহরণ

আপনি কীভাবে বার্তাগুলি পৃষ্ঠায় গতিশীলভাবে যুক্ত হয়ে থাকে তা ক্লিক করুন, নতুন অনুচ্ছেদে সংযুক্ত ইভেন্টগুলির হুক করার কোনও কোড নেই সত্ত্বেও আপনার ক্লিকটি নিবন্ধিত হয়ে পরিচালনা করা হবে। এছাড়াও মনে রাখবেন কিভাবে আপনার হ্যান্ডেলার একটি মানচিত্র মাত্র এন্ট্রি, এবং আপনি এক উপর হ্যান্ডলার document.bodyযে সব ডিসপ্যাচিং আছে। এখন, আপনি সম্ভবত এটির চেয়ে বেশি বেশি টার্গেটযুক্ত কিছুতে এটি রুট করেছেন document.bodyতবে আপনি ধারণাটি পাবেন। এছাড়াও, উপরোক্তগুলিতে আমরা মূলত প্রেরণ করছি idতবে আপনি নিজের মতো জটিল বা সাধারণ হিসাবে ম্যাচিং করতে পারেন।

আধুনিক জাভাস্ক্রিপ্ট লাইব্রেরি যেমন jQuery , প্রোটোটাইপ , YUI , বন্ধ , বা অন্য যে কোনও একটিতে ব্রাউজারের পার্থক্যগুলি সাবলীল করার জন্য এবং প্রান্তের কেসগুলি পরিষ্কারভাবে পরিচালনা করার জন্য ইভেন্ট প্রতিনিধি বৈশিষ্ট্যগুলি সরবরাহ করা উচিত। jQuery অবশ্যই এটির liveএবং delegateফাংশন উভয়ই করে , যা আপনাকে CSS3 নির্বাচকদের (এবং তারপরে) সম্পূর্ণ ব্যাপ্তি ব্যবহার করে হ্যান্ডলারগুলি নির্দিষ্ট করার অনুমতি দেয়।

উদাহরণস্বরূপ, এখানে jQuery ব্যবহার করে সমতুল্য কোডটি (আমি নিশ্চিত না যে jQuery প্রান্তের কেসগুলি উপরের অফ-দ্য কাফ কাঁচা সংস্করণটিকে পরিচালনা করে না):

(function($) {

  $("#button1").live('click', function() {
    display("Button One clicked");
    return false;
  });
  $("#button2").live('click', function() {
    display("Button Two clicked");
    return false;
  });
  $("#outerDiv").live('click', function() {
    display("Outer div clicked");
    return false;
  });
  $("#innerDiv1").live('click', function() {
    display("Inner div 1 clicked, not cancelling event");
  });
  $("#innerDiv2").live('click', function() {
    display("Inner div 2 clicked, cancelling event");
    return false;
  });
  $("p").live('click', function() {
    display("You clicked the message '" + this.innerHTML + "'");
  });

  function display(msg) {
    $("<p>").html(msg).appendTo(document.body);
  }

})(jQuery);

লাইভ কপি


আমি ব্যবহার করতে চাই না Event.target, কারণ এটি সঠিক টার্গেট নয়। সেটা ঠিক. যদি আপনি একটি এর IMGভিতরে একটিতে ক্লিক করেন DIVএবং DIVইভেন্টটি থাকে তবে এটি Event.targetহবে IMGএবং DIVঅবজেক্টটি সুন্দরভাবে পাওয়ার কোনও উপায় নেই । সম্পাদন করা Btw আমি jQuery এর ঘৃণা .live'ইভেন্টে
Rudie

@ রুডি: উত্তর: event.targetআপনি যা বর্ণনা করেছেন তা ভুল নয়, এটি সঠিক। আপনি যদি একটি এর imgঅভ্যন্তরে কোনও ক্লিক করেন divএবং আপনি যা দেখছেন div, event.targetতা হ'ল img(এবং thisহ'ল div)। উপরের দিকে অন্য একবার দেখুন। যে উপাদানটি ক্লিক করা হয়েছিল ( imgউদাহরণস্বরূপ) এবং যে উপাদানটি আপনি দেখছেন (উপরের দিকে সমস্ত উপায়ে নিচে document.body) এর মধ্যে শৃঙ্খলে যে কোনও বিন্দুতে আপনি একটি হ্যান্ডলার সংযুক্ত করতে পারেন । উত্তর live: আমি ব্যাপকভাবে পছন্দ করি delegate, এর আরও সংযুক্ত সংস্করণ live। আমি liveউপরে ব্যবহার করেছি কারণ এটি কাঁচা উদাহরণে আমি যা করেছি তার সবচেয়ে কাছাকাছি ছিল। সেরা,
টিজে ক্রাউডার

4

আপনি এই জাতীয় সাহায্যকারী ফাংশন তৈরি করতে চাইতে পারেন:

function defineAndRun(name, func) {
    window[name] = func;
    func();
}

defineAndRun('addEventsAndStuff', function() {
    alert('oele');
});

4
কেন এটি একটি খারাপ সমাধান? কারন বিশ্বব্যাপী নেমস্পেসে নিবন্ধিত আছে? কে এই জন্য ভোট দিয়েছেন?
রুডি

দুর্দান্ত ধারণা:)) -
ম্যাক্সিমা আলেক্জ

4

আপনার কোডে একটি টাইপ রয়েছে:

(function addEventsAndStuff() {
  alert('oele');
)/*typo here, should be }*/)();

তাই

(function addEventsAndStuff() {
  alert('oele');
 })();

কাজ করে। চিয়ার্স!

মন্তব্যের উপর ভিত্তি করে [ সম্পাদনা করুন ]: এবং এটি চলতে হবে এবং একযোগে ফাংশনটি ফিরে আসতে হবে:

var addEventsAndStuff = (
 function(){
  var addeventsandstuff =  function(){
    alert('oele');
  };
  addeventsandstuff();
  return addeventsandstuff;
 }()
);

বোকা বন্ধনী সব দেখতে একরকম !! ধন্যবাদ! চিয়ারস সত্যই!
রুডি

হ্যাঁ ... তাই হ ... আসলে এটি কাজ করে না। হ্যাঁ, ফাংশনটি তত্ক্ষণাত্ কার্যকর করা হয়েছে, তবে এটি কোথাও নিবন্ধভুক্ত নয়, সুতরাং এটি আবার কল করে ->ReferenceError
রুডি

@ রুডি: সবেমাত্র আবিষ্কার হয়েছে যে কমোডো এডিট সর্বশেষে অপ্টানা স্টুডিওর যা করতে চেয়েছিলেন তার সবকটিই করে (তবে সব সময় ভেঙে পড়ে) এবং তারপরে এটি অত্যন্ত কনফিগারযোগ্য, দ্রুত এবং দরকারী অ্যাডোন দিয়ে ভরপুর। এবং এটি মেলানো বন্ধনীগুলিকে হাইলাইট করে: আপনি এমনকি সেগুলি মেলানো বন্ধনীগুলিকে দৃ red় লাল সতর্কতা রঙ দিতে পারেন! এটি ব্যবহার করে দেখুন, এটি নিখরচায়: activestate.com/komodo-edit
KooiInc

ডুড ... (এবং স্পষ্টতই আমি এটি ডেস্কটপ সম্পাদক হিসাবে নয়, এসও ওয়েব এডিটরটিতে টাইপ করেছি))
রুডি

এবং এটি অনেকগুলি অতিরিক্ত টাইপিং এবং কী এবং কী টাইপ করতে হবে তা মনে করে। আমি মূল (কাজ করছে না) সমাধানটি পছন্দ করেছি তবে
নতুনটি

2

এমনকি ES6 এর সাথে আরও সহজ:

var result = ((a, b) => `${a} ${b}`)('Hello','World')
// result = "Hello World"
var result2 = (a => a*2)(5)
// result2 = 10
var result3 = (concat_two = (a, b) => `${a} ${b}`)('Hello','World')
// result3 = "Hello World"
concat_two("My name", "is Foo")
// "My name is Foo"

তাহলে কীভাবে আবার ফোন করব? এর নাম কি, এটিকে ডাকতে? আপনি কেবল ফলটি রাখছেন, ফাংশনটি নয়।
রুডি 11

এই পদ্ধতিটি কিছু ক্ষেত্রে কেবল তখনই ব্যবহার করা হয় যখন আপনার এটিকে অবিলম্বে কল করার প্রয়োজন হয় এবং আপনি এটি পুনরায় চালু করতে না চান। যাইহোক আমি কীভাবে এটি আবার কল করতে সক্ষম হবে তা দেখানোর জন্য উত্তরটি সম্পাদনা করব, আপনার কী মনে হয়? @ রুডি
আলবার্তো

4
আমার প্রশ্নটি নামকরণ এবং এটি পুনরায় পরিচালনা সম্পর্কে ছিল। concat_twoনিখুঁতভাবে কাজ করে, তবে এটি সর্বদা বিশ্বব্যাপী এটিকে সংজ্ঞায়িত করে, তাই এটি কাজ করে না "use strict"। এটি আমার পক্ষে গুরুত্বপূর্ণ নয়, তবে এটি একটি ক্ষুদ্রতর খারাপ দিক।
রুডি

1

আপনি যদি কোনও ফাংশন তৈরি করতে এবং তাৎক্ষণিকভাবে সম্পাদন করতে চান -

// this will create as well as execute the function a()
(a=function a() {alert("test");})();

// this will execute the function a() i.e. alert("test")
a();

4
সাবধান, আপনি যখন ডান-হাতের মান হিসাবে উপরে বর্ণিত কোনও ফাংশন ব্যবহার করেন (যেমন আপনি উপরে করেন) আপনি একটি নামযুক্ত ফাংশন এক্সপ্রেশন ব্যবহার করছেন যা দুর্ভাগ্যক্রমে বৈধ হওয়া উচিত বিভিন্ন বাস্তবায়নের ক্ষেত্রে (বেশিরভাগ - কোয়েল শক - আইই) )। বিশদ: kangax.github.com/nfe
টিজে

0

এটি করার চেষ্টা করুন:

var addEventsAndStuff = (function(){
    var func = function(){
        alert('ole!');
    };
    func();
    return func;
})();

4
এটি কাছাকাছি, তবে var foo = (function() {...})();অ্যাসাইনমেন্টের আগে ফাংশনটি কল করে। প্রথম বন্ধনী অ্যাসাইনমেন্ট অন্তর্ভুক্ত করা প্রয়োজন। (আপনি তারপরে কল করতে চান ))
ডেভিড

এটিও অনেকগুলি টাইপিং এবং কী টাইপ করতে হবে তা মনে করে। তারপরে আমি বরং আমার বর্তমান কলগুলি ব্যবহার করব।
রুডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.