javascript - var functionName=function(){} vs ফাংশন ফাংশন নাম(){}




syntax idioms (20)

অন্য মন্তব্যকারীরা ইতিমধ্যে উপরে দুটি রূপের অর্থাত্ পার্থক্য আচ্ছাদিত করেছে। আমি একটি স্টাইলিস্টিক পার্থক্য নোট করতে চেয়েছিলেন: শুধুমাত্র "বরাদ্দকরণ" বৈচিত্র্য অন্য বস্তুর একটি সম্পত্তি সেট করতে পারেন।

আমি প্রায়ই এই মত একটি প্যাটার্ন সঙ্গে জাভাস্ক্রিপ্ট মডিউল নির্মাণ:

(function(){
    var exports = {};

    function privateUtil() {
            ...
    }

    exports.publicUtil = function() {
            ...
    };

    return exports;
})();

এই প্যাটার্নের সাহায্যে, আপনার ব্যক্তিগত ফাংশনগুলি সর্বদা অ্যাসাইনমেন্ট ব্যবহার করবে, যখন আপনার ব্যক্তিগত ফাংশন ঘোষণা ব্যবহার করবে।

(উল্লেখ্য যে নিয়োগের পরে বিবৃতির জন্য একটি সেমিকোলন প্রয়োজন, যখন ঘোষণা এটি নিষিদ্ধ করে।)

আমি সম্প্রতি অন্য কারো জাভাস্ক্রিপ্ট কোড বজায় রাখতে শুরু করেছি। আমি বাগ সংশোধন করছি, বৈশিষ্ট্য যুক্ত করছি, এবং কোডটি পরিষ্কার করার চেষ্টা করছি এবং এটি আরও সামঞ্জস্যপূর্ণ করে তুলছি।

পূর্ববর্তী বিকাশকারী ফাংশন ঘোষণা করার দুটি উপায়ে ব্যবহার করে এবং এটির পিছনে কোনো কারণ থাকলে আমি কাজ করতে পারছি না।

দুটি উপায় হল:

var functionOne = function() {
    // Some code
};
function functionTwo() {
    // Some code
}

এই দুটি বিভিন্ন পদ্ধতি ব্যবহার করার জন্য কি কারণ এবং প্রতিটি এর পেশাদার এবং বিপর্যয় কি? এমন কি এমন কিছু আছে যা এক পদ্ধতিতে করা যায় যা অন্যের সাথে করা যায় না?


আপনি যে দুটি কোড স্নিপেট পোস্ট করেছেন সেখানে প্রায় সব উদ্দেশ্যেই একই আচরণ করবেন।

যাইহোক, আচরণের পার্থক্য হল যে প্রথম রূপটি ( var functionOne = function() {} ) সহ, সেই ফাংশনটিকে শুধুমাত্র কোডের পরেই বলা যেতে পারে।

দ্বিতীয় রূপ ( function functionTwo() ) সঙ্গে, ফাংশন ঘোষণা করা হয় যেখানে উপরের কোড রান যে ফাংশন ঘোষণা করা হয়।

এটি কারণ প্রথম রূপের সাথে, ফাংশনটি চলমান সময়ে foo variable এ নির্ধারিত হয়। দ্বিতীয়ত, ফাংশনটি সেই আইডেন্টিফায়ারকে নির্ধারিত হয়, foo , পার্স সময়।

আরো প্রযুক্তিগত তথ্য

জাভাস্ক্রিপ্ট ফাংশন সংজ্ঞা তিনটি উপায় আছে।

  1. আপনার প্রথম স্নিপেট একটি ফাংশন অভিব্যক্তি দেখায়। এটি একটি ফাংশন তৈরি করার জন্য "ফাংশন" অপারেটর ব্যবহার করে থাকে - যে অপারেটরের ফলাফলটি কোনও পরিবর্তনশীল বা বস্তুর সম্পত্তিতে সংরক্ষণ করা যেতে পারে। ফাংশন অভিব্যক্তি যে ভাবে শক্তিশালী। ফাংশন এক্সপ্রেশনটি প্রায়শই একটি "বেনামী ফাংশন" বলা হয়, কারণ এটির নাম থাকতে হবে না,
  2. আপনার দ্বিতীয় উদাহরণ একটি ফাংশন ঘোষণা । এটি একটি ফাংশন তৈরি করার জন্য "ফাংশন" বিবৃতি ব্যবহার করে। ফাংশন পার্স সময় সময়ে উপলব্ধ করা হয় এবং যে সুযোগ কোথাও বলা যেতে পারে। আপনি এখনও এটি একটি পরিবর্তনশীল বা বস্তুর সম্পত্তি পরে সংরক্ষণ করতে পারেন।
  3. একটি ফাংশন সংজ্ঞায়িত করার তৃতীয় উপায় হল "ফাংশন ()" গঠনকারী , যা আপনার মূল পোস্টে দেখানো হয় না। এটি ব্যবহার করার পরামর্শ দেওয়া হয় না কারণ এটি eval() , যা তার সমস্যাগুলির মতো একই ভাবে কাজ করে।

একটি গুরুত্বপূর্ণ কারণ হল আপনার নামস্থানটির "রুট" হিসাবে এক এবং একমাত্র পরিবর্তনশীল যুক্ত করা ...

var MyNamespace = {}
MyNamespace.foo= function() {

}

অথবা

var MyNamespace = {
  foo: function() {
  },
  ...
}

নামস্থান জন্য অনেক কৌশল আছে। এটি জাভাস্ক্রিপ্ট মডিউল প্রচুর পরিমাণে উপলব্ধ সঙ্গে আরও গুরুত্বপূর্ণ হয়ে ওঠে।

এছাড়াও কিভাবে আমি জাভাস্ক্রিপ্ট একটি নামস্থান ঘোষণা করবেন?


এখানে ফাংশন তৈরি করে এমন স্ট্যান্ডার্ড ফর্মগুলিতে রান্ডাউন্ডটি রয়েছে: (মূলত অন্য প্রশ্নটির জন্য লিখিত, কিন্তু ক্যানোনিকাল প্রশ্নে স্থানান্তরিত হওয়ার পরে এটির অভিযোজিত।)

শর্তাবলী:

দ্রুত তালিকা:

  • ফাংশন ঘোষণা

  • "বেনামী" function এক্সপ্রেশন (যা শব্দটি সত্ত্বেও, কখনও কখনও নামগুলির সাথে ফাংশন তৈরি করে)

  • নামকরণ function এক্সপ্রেশন

  • অ্যাক্সেসার ফাংশন ইনস্যুলাইজার (ES5 +)

  • অ্যারো ফাংশন এক্সপ্রেশন (ES2015 +) (যা, বেনামী ফাংশন এক্সপ্রেশনগুলির মতো, একটি স্পষ্ট নাম অন্তর্ভুক্ত করে না এবং এখনও নামগুলির সাথে ফাংশন তৈরি করতে পারে)

  • অবজেক্ট ইনিশিয়ালাইজারের পদ্ধতি ঘোষণা (ES2015 +)

  • class নির্মাতা এবং পদ্ধতি ঘোষণা (ES2015 +)

ফাংশন ঘোষণা

প্রথম ফর্ম একটি ফাংশন ঘোষণা , যা এই মত দেখাচ্ছে:

function x() {
    console.log('x');
}

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

কোনও ধাপ-ধাপ কোড কার্যকর হওয়ার আগে এটি প্রদর্শিত হয় এমন প্রেক্ষাপটে অ্যাক্সেসটি প্রবেশ করে যখন একটি ফাংশন ঘোষণা প্রক্রিয়া করা হয়। এটি তৈরি করা ফাংশনটি একটি সঠিক নাম (উপরের উদাহরণে x ) দেওয়া হয় এবং সেই নামটি সেই সুযোগে রাখা হয় যেখানে ঘোষণাটি প্রদর্শিত হয়।

যেহেতু এটি একই প্রেক্ষাপটে যে কোনও ধাপে ধাপে কোডের আগে প্রক্রিয়াকরণ করা হয়, তাই আপনি এটির মতো কিছু করতে পারেন:

x(); // Works even though it's above the declaration
function x() {
    console.log('x');
}

ES2015 পর্যন্ত, স্পেসটি যদি কোনও নিয়ন্ত্রণ কাঠামোর ভিতরে কোনও ফাংশন ঘোষণাকারী হিসাবে try , if , switch , while , ইত্যাদির মতো করা থাকে তবে কোনও জাভাস্ক্রিপ্ট ইঞ্জিন কী করবে তা জুড়েছে না:

if (someCondition) {
    function foo() {    // <===== HERE THERE
    }                   // <===== BE DRAGONS
}

এবং তারা ধাপে ধাপে কোড চালানোর আগে প্রক্রিয়াভুক্ত হয়, এটি নিয়ন্ত্রণ নিয়ন্ত্রণে থাকা অবস্থায় কী করা উচিত তা জানা কঠিন।

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

ES2015 হিসাবে, স্পেসিফিকেশন কি করতে বলে। আসলে, এটি করার জন্য তিনটি পৃথক জিনিস দেয়:

  1. যদি কোনও ওয়েব ব্রাউজারে আলগা মোড না থাকে তবে জাভাস্ক্রিপ্ট ইঞ্জিনটি এক জিনিস করতে অনুমিত হয়
  2. যদি কোনও ওয়েব ব্রাউজারে আলগা মোডে, জাভাস্ক্রিপ্ট ইঞ্জিনটি অন্য কিছু করতে অনুমিত হয়
  3. যদি কঠোর মোডে (ব্রাউজার বা না), জাভাস্ক্রিপ্ট ইঞ্জিনটি অন্য কিছু করতে অনুমিত হয়

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

"use strict";
if (someCondition) {
    foo();               // Works just fine
    function foo() {
    }
}
console.log(typeof foo); // "undefined" (`foo` is not in scope here
                         // because it's not in the same block)

"বেনামী" function এক্সপ্রেশন

দ্বিতীয় সাধারণ ফর্মটি একটি বেনামী ফাংশন অভিব্যক্তি বলা হয়:

var y = function () {
    console.log('y');
};

সমস্ত এক্সপ্রেশন লেগেছে, যখন এটি কোডের ধাপে ধাপে কার্যকর হয় তখন এটি মূল্যায়ন করা হয়।

ES5 এ, যে ফাংশনটির সৃষ্টি হয়েছে তার কোন নাম নেই (এটি বেনামী)। ES2015 এ, ফাংশনটিকে প্রসঙ্গ থেকে এটি উল্লেখ করে যদি সম্ভব হয় তবে একটি নাম বরাদ্দ করা হয়। উপরের উদাহরণে, নাম y । ফাংশনটি একটি সম্পত্তি প্রারম্ভিকের মান যখন কিছু অনুরূপ হয়। (যখন এটি ঘটে এবং নিয়মগুলি সম্পর্কে বিস্তারিত জানার জন্য, SetFunctionName মধ্যে SetFunctionName অনুসন্ধান করুন - এটি সমস্ত জায়গায় প্রদর্শিত হবে ।)

নামকরণ function এক্সপ্রেশন

তৃতীয় ফর্মটি একটি নামযুক্ত ফাংশন এক্সপ্রেশন ("NFE"):

var z = function w() {
    console.log('zw')
};

এই সৃষ্টির ফাংশন একটি সঠিক নাম আছে (এই ক্ষেত্রে w )। সমস্ত অভিব্যক্তি লেগেছে, যখন এটি কোডের ধাপে ধাপে কার্যকর করা হয় তখন এটি মূল্যায়ন করা হয়। ফাংশনের নামটি কোনও অভিব্যক্তিতে যুক্ত হয় না যা অভিব্যক্তিটি উপস্থিত হয়; নাম ফাংশন নিজেই মধ্যে সুযোগ হয়:

var z = function w() {
    console.log(typeof w); // "function"
};
console.log(typeof w);     // "undefined"

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

অ্যাক্সেসার ফাংশন ইনস্যুলাইজার (ES5 +)

কখনও কখনও ফাংশন মূলত unnoticed মধ্যে ছিঁচকে চুরি করা যাবে; যে অ্যাক্সেস ফাংশন সঙ্গে ক্ষেত্রে। এখানে একটি উদাহরণ:

var obj = {
    value: 0,
    get f() {
        return this.value;
    },
    set f(v) {
        this.value = v;
    }
};
console.log(obj.f);         // 0
console.log(typeof obj.f);  // "number"

মনে রাখবেন যে যখন আমি ফাংশন ব্যবহার করি, তখন আমি () ব্যবহার করি নি! যেহেতু এটি একটি সম্পত্তি জন্য একটি অ্যাক্সেসার ফাংশন । আমরা স্বাভাবিক উপায়ে সম্পত্তিটি পেতে এবং সেট করি, কিন্তু দৃশ্যগুলির পিছনে, ফাংশনটি বলা হয়।

আপনি Object.defineProperty , Object.defineProperties এবং Object.create . Object.create কম পরিচিত দ্বিতীয় যুক্তি সহ Object.defineProperty ফাংশনগুলি তৈরি করতে পারেন।

তীর ফাংশন এক্সপ্রেশন (ES2015 +)

ES2015 আমাদের তীর ফাংশন এনেছে। এখানে একটি উদাহরণ:

var a = [1, 2, 3];
var b = a.map(n => n * 2);
console.log(b.join(", ")); // 2, 4, 6

দেখুন যে n => n * 2 map() লুকানো জিনিসটি map() কল আছে? যে একটি ফাংশন।

তীর ফাংশন সম্পর্কে কিছু জিনিস:

  1. তারা তাদের নিজস্ব আছে না। পরিবর্তে, তারা সংজ্ঞায়িত যেখানে প্রসঙ্গে this বন্ধ । (তারা arguments বন্ধ করে এবং যেখানে প্রাসঙ্গিক, super ।) এর অর্থ এই যে তাদের মধ্যে এটি একই রকম যেখানে তারা তৈরি হয়, এবং পরিবর্তন করা যাবে না।

  2. আপনি উপরের উপরে লক্ষ্য করেছেন, আপনি কীওয়ার্ড function ব্যবহার করবেন না; পরিবর্তে, আপনি => ব্যবহার =>

n => n * 2 উদাহরণ উপরে তাদের একটি ফর্ম। ফাংশনটি পাস করার জন্য আপনার যদি একাধিক আর্গুমেন্ট থাকে তবে আপনি পিতার ব্যবহার করুন:

var a = [1, 2, 3];
var b = a.map((n, i) => n * i);
console.log(b.join(", ")); // 0, 2, 6

(মনে রাখবেন যে Array#map প্রথম আর্গুমেন্ট হিসাবে এন্ট্রি পাস করে, এবং দ্বিতীয় হিসাবে সূচক।)

উভয় ক্ষেত্রে, ফাংশন শরীর শুধু একটি অভিব্যক্তি; ফাংশনের রিটার্ন মান স্বয়ংক্রিয়ভাবে সেই অভিব্যক্তিটির ফলাফল হবে (আপনি একটি সুস্পষ্ট return ব্যবহার করবেন না)।

আপনি যদি শুধুমাত্র একটি একক অভিব্যক্তি থেকে বেশি কিছু করছেন তবে স্বাভাবিক হিসাবে {} এবং একটি সুস্পষ্ট return (যদি আপনাকে একটি মান ফেরত দিতে হয়) ব্যবহার করুন।

var a = [
  {first: "Joe", last: "Bloggs"},
  {first: "Albert", last: "Bloggs"},
  {first: "Mary", last: "Albright"}
];
a = a.sort((a, b) => {
  var rv = a.last.localeCompare(b.last);
  if (rv === 0) {
    rv = a.first.localeCompare(b.first);
  }
  return rv;
});
console.log(JSON.stringify(a));

{ ... } ছাড়া সংস্করণটি একটি এক্সপ্রেশন শরীর বা সংক্ষিপ্ত শরীরের সাথে একটি তীর ফাংশন বলা হয়। (এছাড়াও: একটি সংক্ষেপণ তীর ফাংশন।) { ... } শরীরের সংজ্ঞায়িতকারী একটি ফাংশন শরীরের সাথে একটি তীর ফাংশন। (এছাড়াও: একটি verbose তীর ফাংশন।)

অবজেক্ট ইনিশিয়ালাইজারের পদ্ধতি ঘোষণা (ES2015 +)

ES2015 একটি ফাংশন রেফারেন্স যে একটি সম্পত্তি ঘোষণা একটি ছোট আকার অনুমতি দেয়; এটা দেখে মনে হচ্ছে:

var o = {
    foo() {
    }
};

ES5 এবং এর সমতুল্য হবে:

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

class নির্মাতা এবং পদ্ধতি ঘোষণা (ES2015 +)

ES2015 ঘোষিত কনস্ট্রাক্টর এবং পদ্ধতি সহ আমাদের class সিনট্যাক্স এনেছে:

class Person {
    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    getFullName() {
        return this.firstName + " " + this.lastName;
    }
}

উপরে দুটি ফাংশন ঘোষণা রয়েছে: কনস্ট্রাক্টরটির জন্য একটি, যার নামটি Person , এবং getFullName জন্য একটি, যা getFullName দেওয়া একটি ফাংশন।


পার্থক্য হল functionOne একটি ফাংশন এক্সপ্রেশন এবং তাই লাইনটি পৌঁছে গেলে কেবলমাত্র সংজ্ঞায়িত করা হয়, তবে functionTwo একটি ফাংশন ঘোষণাকারী এবং এটি যত তাড়াতাড়ি তার পার্শ্ববর্তী ফাংশন বা স্ক্রিপ্টটি সম্পাদন করা হয় ( hoisting কারণে) সংজ্ঞায়িত করা হয়।

উদাহরণস্বরূপ, একটি ফাংশন অভিব্যক্তি:

// TypeError: functionOne is not a function
functionOne();

var functionOne = function() {
  console.log("Hello!");
};

এবং, একটি ফাংশন ঘোষণা:

// Outputs: "Hello!"
functionTwo();

function functionTwo() {
  console.log("Hello!");
}

এর অর্থ হল আপনি ফাংশন ঘোষণাগুলি ব্যবহার করে ফাংশন সংজ্ঞায়িত করতে পারবেন না:

if (test) {
   // Error or misbehavior
   function functionThree() { doSomething(); }
}

উপরে প্রকৃতপক্ষে test এর মান নির্বিশেষে functionThree সংজ্ঞায়িত functionThree - যতক্ষণ না use strict কার্যকর হয়, এ ক্ষেত্রে এটি কেবল একটি ত্রুটি বাড়ায়।


প্রথমত আমি গ্রেগকে সংশোধন করতে চাই: function abc(){} খুব দণ্ডিত হয় - নাম abc এই সংজ্ঞাটির সম্মুখীন হওয়ার সুযোগে সংজ্ঞায়িত করা হয়। উদাহরণ:

function xyz(){
  function abc(){};
  // abc is defined here...
}
// ...but not here

দ্বিতীয়ত, উভয় শৈলী একত্রিত করা সম্ভব:

var xyz = function abc(){};

xyz স্বাভাবিক হিসাবে সংজ্ঞায়িত করা যাচ্ছে, abc সমস্ত ব্রাউজারে অনির্ধারিত কিন্তু ইন্টারনেট এক্সপ্লোরার - এটি সংজ্ঞায়িত হচ্ছে উপর নির্ভর করবেন না। কিন্তু এটি তার শরীরের ভিতরে সংজ্ঞায়িত করা হবে:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

যদি আপনি সমস্ত ব্রাউজারে ওরফে ফাংশনগুলি চান তবে এই ধরনের ঘোষণাটি ব্যবহার করুন:

function abc(){};
var xyz = abc;

এই ক্ষেত্রে, xyz এবং abc উভয় একই বস্তুর aliases হয়:

console.log(xyz === abc); // prints "true"

যৌথ শৈলী ব্যবহার করার জন্য একটি বাধ্যতামূলক কারণ হল ফাংশন অবজেক্টগুলির "নাম" বৈশিষ্ট্য ( ইন্টারনেট এক্সপ্লোরার দ্বারা সমর্থিত নয় )। আপনি যখন মত একটি ফাংশন সংজ্ঞায়িত মূলত

function abc(){};
console.log(abc.name); // prints "abc"

তার নাম স্বয়ংক্রিয়ভাবে বরাদ্দ করা হয়। কিন্তু যখন আপনি এটি মত সংজ্ঞায়িত

var abc = function(){};
console.log(abc.name); // prints ""

তার নাম খালি - আমরা একটি বেনামী ফাংশন তৈরি এবং কিছু পরিবর্তনশীল এটি বরাদ্দ।

যৌথ শৈলী ব্যবহার করার আরেকটি ভাল কারণ বাহ্যিক ব্যবহারকারীদের জন্য একটি দীর্ঘ অ-দ্বন্দ্বমূলক নাম সরবরাহ করার সময় নিজেকে উল্লেখ করার জন্য একটি স্বল্প অভ্যন্তরীণ নাম ব্যবহার করা হয়:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively:
  shortcut(n - 1);
  // ...
  // Let it pass itself as a callback:
  someFunction(shortcut);
  // ...
}

উপরের উদাহরণে আমরা বাহ্যিক নামের সাথে একই কাজ করতে পারি, তবে এটি খুব অচল (এবং ধীর) হবে।

(নিজেকে উল্লেখ করার আরেকটি উপায় arguments.callee ব্যবহার করা যা এখনও অপেক্ষাকৃত দীর্ঘ, এবং কঠোর মোডে সমর্থিত নয়।)

গভীর নিচে, জাভাস্ক্রিপ্ট উভয় বিবৃতি পৃথকভাবে আচরণ করে। এটি একটি ফাংশন ঘোষণা:

function abc(){}

এখানে abc বর্তমান সুযোগে সর্বত্র সংজ্ঞায়িত করা হয়:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

এছাড়াও, এটি একটি return বিবৃতি মাধ্যমে উত্তোলন:

// We can call it here
abc(); // Works
return;
function abc(){}

এটি একটি ফাংশন এক্সপ্রেশন:

var xyz = function(){};

xyz এখানে অ্যাসাইনমেন্ট বিন্দু থেকে সংজ্ঞায়িত করা হয়:

// We can't call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

ফাংশন ঘোষণা বনাম ফাংশন এক্সপ্রেশন গ্রেগ দ্বারা প্রদর্শিত একটি পার্থক্য কেন আসল কারণ।

মজার ব্যাপার:

var xyz = function abc(){};
console.log(xyz.name); // Prints "abc"

ব্যক্তিগতভাবে, আমি "ফাংশন এক্সপ্রেশন" ঘোষণার পছন্দ করি কারণ এই ভাবে আমি দৃশ্যমানতা নিয়ন্ত্রণ করতে পারি। যখন আমি মত ফাংশন সংজ্ঞায়িত

var abc = function(){};

আমি স্থানীয়ভাবে ফাংশন সংজ্ঞায়িত যে জানি। যখন আমি মত ফাংশন সংজ্ঞায়িত

abc = function(){};

আমি জানি যে আমি বিশ্বব্যাপী এটি সরবরাহ করেছি যে আমি scopes শৃঙ্খলে যেকোনো জায়গায় abc সংজ্ঞায়িত করে নি। সংজ্ঞা এই শৈলী eval() ব্যবহৃত যখন এমনকি স্থিতিশীল। যদিও সংজ্ঞা

function abc(){};

প্রেক্ষাপটে নির্ভর করে এবং আপনাকে প্রকৃতপক্ষে যেখানে এটি প্রকৃতপক্ষে সংজ্ঞায়িত করা হয় অনুমান করতে পারে, বিশেষত eval() এর উত্তর - উত্তরটি হল: এটি ব্রাউজারের উপর নির্ভর করে।


"নামযুক্ত ফাংশন স্ট্যাক ট্রেসগুলিতে দেখানো" আলোকে, আধুনিক জাভাস্ক্রিপ্ট ইঞ্জিন আসলে বেনামী ফাংশনগুলিকে প্রতিনিধিত্ব করতে সক্ষম।

এই লেখাটি অনুসারে, ভি 8, স্পাইডারমঙ্কি, চক্র এবং নাইট্রো সর্বদা নাম অনুসারে তাদের নামগুলি উল্লেখ করে। এটি প্রায়শই এটির শনাক্তকারীর দ্বারা একটি বেনামী ফাংশনটিকে উল্লেখ করে।

SpiderMonkey অন্য ফাংশন থেকে ফেরানো একটি বেনামী ফাংশন নাম খুঁজে বের করতে পারেন। বাকিরা পারে না।

আপনি সত্যিই, সত্যিই আপনার ইটারারেটর এবং সাফল্য callbacks ট্রেস দেখাতে চেয়েছিলেন, আপনি তাদের নাম পারে ...

[].forEach(function iterator() {});

কিন্তু বেশিরভাগ ক্ষেত্রেই এটির উপর চাপ সৃষ্টি করা ঠিক নয়।

জোয়ার ( Fiddle )

'use strict';

var a = function () {
    throw new Error();
},
    b = function b() {
        throw new Error();
    },
    c = function d() {
        throw new Error();
    },
    e = {
        f: a,
        g: b,
        h: c,
        i: function () {
            throw new Error();
        },
        j: function j() {
            throw new Error();
        },
        k: function l() {
            throw new Error();
        }
    },
    m = (function () {
        return function () {
            throw new Error();
        };
    }()),
    n = (function () {
        return function n() {
            throw new Error();
        };
    }()),
    o = (function () {
        return function p() {
            throw new Error();
        };
    }());

console.log([a, b, c].concat(Object.keys(e).reduce(function (values, key) {
    return values.concat(e[key]);
}, [])).concat([m, n, o]).reduce(function (logs, func) {

    try {
        func();
    } catch (error) {
        return logs.concat('func.name: ' + func.name + '\n' +
                           'Trace:\n' +
                           error.stack);
        // Need to manually log the error object in Nitro.
    }

}, []).join('\n\n'));

V8

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at a (http://localhost:8000/test.js:4:11)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: b
Trace:
Error
    at b (http://localhost:8000/test.js:7:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: d
Trace:
Error
    at d (http://localhost:8000/test.js:10:15)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at e.i (http://localhost:8000/test.js:17:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: j
Trace:
Error
    at j (http://localhost:8000/test.js:20:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: l
Trace:
Error
    at l (http://localhost:8000/test.js:23:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: 
Trace:
Error
    at http://localhost:8000/test.js:28:19
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: n
Trace:
Error
    at n (http://localhost:8000/test.js:33:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27

func.name: p
Trace:
Error
    at p (http://localhost:8000/test.js:38:19)
    at http://localhost:8000/test.js:47:9
    at Array.reduce (native)
    at http://localhost:8000/test.js:44:27 test.js:42

মাকরশা টাকা

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:5
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:9
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: 
Trace:
m</<@http://localhost:8000/test.js:28:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1


func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:13
@http://localhost:8000/test.js:47:9
@http://localhost:8000/test.js:54:1

চক্র

func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at a (http://localhost:8000/test.js:4:5)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at b (http://localhost:8000/test.js:7:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at d (http://localhost:8000/test.js:10:9)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at e.i (http://localhost:8000/test.js:17:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at j (http://localhost:8000/test.js:20:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at l (http://localhost:8000/test.js:23:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at Anonymous function (http://localhost:8000/test.js:28:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at n (http://localhost:8000/test.js:33:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)


func.name: undefined
Trace:
Error
   at p (http://localhost:8000/test.js:38:13)
   at Anonymous function (http://localhost:8000/test.js:47:9)
   at Global code (http://localhost:8000/test.js:42:1)

নিত্র

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:4:22
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: b
Trace:
[email protected]://localhost:8000/test.js:7:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: d
Trace:
[email protected]://localhost:8000/test.js:10:26
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
[email protected]://localhost:8000/test.js:17:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: j
Trace:
[email protected]://localhost:8000/test.js:20:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: l
Trace:
[email protected]://localhost:8000/test.js:23:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: 
Trace:
http://localhost:8000/test.js:28:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: n
Trace:
[email protected]://localhost:8000/test.js:33:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

func.name: p
Trace:
[email protected]://localhost:8000/test.js:38:30
http://localhost:8000/test.js:47:13
[email protected][native code]
global [email protected]://localhost:8000/test.js:44:33

new Function()একটি স্ট্রিং মধ্যে ফাংশন শরীর পাস করতে ব্যবহার করা যেতে পারে। এবং তাই এই গতিশীল ফাংশন তৈরি করতে ব্যবহার করা যেতে পারে। এছাড়াও স্ক্রিপ্ট নির্বাহ ছাড়া স্ক্রিপ্ট পাস।

var func = new Function("x", "y", "return x*y;");
function secondFunction(){
   var result;
   result = func(10,20);
   console.log ( result );
}

secondFunction()

কর্মক্ষমতা সম্পর্কে:

নতুন নতুন সংস্করণ V8চালু হ'ল আন্ডার-হুড অপ্টিমাইজেশান এবং তাই করেছে SpiderMonkey

এক্সপ্রেশন এবং ঘোষণা মধ্যে এখন প্রায় কোন পার্থক্য আছে।
ফাংশন অভিব্যক্তি এখন দ্রুত হতে প্রদর্শিত হবে

ক্রোম 62.0.3202

ফায়ারফক্স 55

ক্রোম ক্যানারি 63.0.3225


Anonymousফাংশন এক্সপ্রেশন ফাংশন অভিব্যক্তি বিরুদ্ধে ভাল কর্মক্ষমতা উপস্থিত প্রদর্শিত হবেNamed


ফায়ারফক্স ক্রোম ক্যানারি ক্রোম


আপনি বস্তু তৈরি করতে এই ফাংশন ব্যবহার করবে, আপনি পাবেন:

var objectOne = new functionOne();
console.log(objectOne.__proto__); // prints "Object {}" because constructor is an anonymous function

var objectTwo = new functionTwo();
console.log(objectTwo.__proto__); // prints "functionTwo {}" because constructor is a named function

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

আমার কোড আছে 160 টি স্বাধীনভাবে ডিজাইন করা ব্র্যান্ডিং দিয়ে। বেশিরভাগ কোড ভাগ করা ফাইলগুলিতে থাকে তবে ব্র্যান্ডিং-নির্দিষ্ট স্টাফ একটি পৃথক ফাইলে থাকে, প্রতিটি ব্র্যান্ডিংয়ের জন্য।

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

পরিবর্তনশীল সিনট্যাক্স ব্যবহার করে, আমি ভাগ করা কোডের মধ্যে পরিবর্তনশীল (একটি ফাংশন পয়েন্টার) ঘোষণা করতে পারি এবং একটি ছোট্ট স্টাব ফাংশন বরাদ্দ করতে পারি, বা নিলতে সেট করতে পারি।

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

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


আমি নিচে পার্থক্য তালিকাভুক্ত করছি:

  1. একটি ফাংশন ঘোষণা কোডে যে কোন জায়গায় স্থাপন করা যেতে পারে। কোডটিতে সংজ্ঞাটি উপস্থিত হওয়ার আগে এটি আহ্বান করা হলেও এটি ফাংশন ঘোষণাকে মেমরির জন্য প্রতিশ্রুতিবদ্ধ করা হয় বা পৃষ্ঠাতে যেকোনো কোড কার্যকর করার আগে এটি ফাঁকা করা হয়।

    নীচের ফাংশন তাকান:

    function outerFunction() {
        function foo() {
           return 1;
        }
        return foo();
        function foo() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 2
    

    কারণ, মৃত্যুদন্ড কার্যকর করার সময়, এটি মনে হচ্ছে: -

    function foo() {  // The first function declaration is moved to top
        return 1;
    }
    function foo() {  // The second function declaration is moved to top
        return 2;
    }
    function outerFunction() {
        return foo();
    }
    alert(outerFunction()); //So executing from top to bottom,
                            //the last foo() returns 2 which gets displayed
    

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

    ফাংশন এক্সপ্রেশন ব্যবহার করে একই ফাংশন:

    function outerFunction() {
        var foo = function() {
           return 1;
        }
        return foo();
        var foo = function() {
           return 2;
        }
    }
    alert(outerFunction()); // Displays 1
    

    কারণ মৃত্যুদন্ড কার্যকর করার সময় এটি মনে হচ্ছে:

    function outerFunction() {
       var foo = undefined;
       var foo = undefined;
    
       foo = function() {
          return 1;
       };
       return foo ();
       foo = function() {   // This function expression is not reachable
          return 2;
       };
    }
    alert(outerFunction()); // Displays 1
    
  2. অ-ফাংশন ব্লকগুলিতে ফাংশন ঘোষণাগুলি লিখতে নিরাপদ নয় যেমন যদি তারা অ্যাক্সেসযোগ্য না হয়।

    if (test) {
        function x() { doSomething(); }
    }
    
  3. নিচের মত ফাংশন এক্সপ্রেশন, সংস্করণ 9 এর আগে ইন্টারনেট এক্সপ্লোরার ব্রাউজারে কাজ করতে পারে না।

    var today = function today() {return new Date()}
    

একটি ফাংশন ঘোষণা এবং একটি পরিবর্তনশীল নির্ধারিত একটি ফাংশন অভিব্যক্তি বাঁধাই প্রতিষ্ঠিত একবার একই আচরণ।

সেখানে একটি পার্থক্য অবশ্য হয় কিভাবে এবং যখন ফাংশন বস্তুর আসলে তার পরিবর্তনশীল সঙ্গে সংশ্লিষ্ট। এই পার্থক্য জাভাস্ক্রিপ্ট মধ্যে পরিবর্তনশীল hoisting বলা প্রক্রিয়া কারণে ।

মূলত, সমস্ত ফাংশন ঘোষণা এবং পরিবর্তনশীল ঘোষণা ফাংশনের শীর্ষে ঘোষিত হয় যেখানে ঘোষণাকারী হয় (এই কারণে আমরা জাভাস্ক্রিপ্টটির কার্যকারিতা দশা বলে )।

  • যখন একটি ফাংশন ঘোষণাকৃত করা হয়, ফাংশন শরীরটি "অনুসরণ করে" তখন ফাংশন শরীর মূল্যায়ন করা হয়, পরিবর্তনশীল অবিলম্বে একটি ফাংশন বস্তুর সাথে আবদ্ধ করা হবে।

  • যখন একটি পরিবর্তনশীল ঘোষণায় উত্তোলন করা হয়, তখন প্রাথমিকভাবে অনুসরণ করা হয় না , তবে "পিছনে বাম" হয়। পরিবর্তনশীল undefinedফাংশন শরীরের শুরুতে শুরু হয়, এবং কোড তার মূল অবস্থান একটি মান বরাদ্দ করা হবে । (প্রকৃতপক্ষে, এটি প্রতিটি অবস্থানে একটি মান বরাদ্দ করা হবে যেখানে একই নামে একটি পরিবর্তনশীল ঘোষণাটি ঘটে।)

Hoisting আদেশ এছাড়াও গুরুত্বপূর্ণ: ফাংশন ঘোষণা একই নামের সঙ্গে পরিবর্তনশীল ঘোষণা উপর অগ্রাধিকার নিতে, এবং শেষ ফাংশন ঘোষণা একই নামের সঙ্গে আগের ফাংশন ঘোষণা উপর অগ্রাধিকার লাগে।

কিছু উদাহরণ...

var foo = 1;
function bar() {
  if (!foo) {
    var foo = 10 }
  return foo; }
bar() // 10

ভেরিয়েবলটি fooফাংশনের শীর্ষে আটকানো হয় undefined, যাতে শুরু !fooহয় true, তাই fooএটি নির্ধারিত হয় 10fooবাইরে barএর সুযোগ কোন ভূমিকা পালন করে এবং অস্পৃষ্ট হয়।

function f() {
  return a; 
  function a() {return 1}; 
  var a = 4;
  function a() {return 2}}
f()() // 2

function f() {
  return a;
  var a = 4;
  function a() {return 1};
  function a() {return 2}}
f()() // 2

ফাংশন ঘোষণা পরিবর্তনশীল ঘোষণা উপর অগ্রাধিকার, এবং শেষ ফাংশন ঘোষণা "লাঠি" ঘোষণা।

function f() {
  var a = 4;
  function a() {return 1}; 
  function a() {return 2}; 
  return a; }
f() // 4

এই উদাহরণটি aফাংশন অবজেক্টের সাথে শুরু হয় যার ফলে দ্বিতীয় ফাংশন ঘোষণার মূল্যায়ন করা হয় এবং তারপরে বরাদ্দ করা হয় 4

var a = 1;
function b() {
  a = 10;
  return;
  function a() {}}
b();
a // 1

এখানে ফাংশন ঘোষণার প্রথম, ঘোষণা এবং পরিবর্তনশীল আরম্ভ করা হয় a। পরবর্তী, এই পরিবর্তনশীল বরাদ্দ করা হয় 10। অন্য কথায়: বরাদ্দ বাইরের পরিবর্তনশীল বরাদ্দ করা হয় না a


এটি ফাংশন ঘোষণা করার মাত্র দুটি সম্ভাব্য উপায়, এবং দ্বিতীয়ত, আপনি ঘোষণার আগে ফাংশনটি ব্যবহার করতে পারেন।


গ্রেগ এর উত্তর একটি ভাল ব্যাখ্যা

functionTwo();
function functionTwo() {
}

কেন কোন ত্রুটি? আমরা সর্বদা শেখানো হয় যে এক্সপ্রেশন উপরের থেকে নীচে (??)

কারণ:

ফাংশন ঘোষণা এবং পরিবর্তনশীল ঘোষণা সর্বদা জাভাস্ক্রিপ্ট ইন্টারপ্রেটার দ্বারা তাদের ধারণকারী সুযোগের উপরে অদৃশ্যভাবে সরানো ( hoisted ) করা হয়। ফাংশন পরামিতি এবং ভাষা সংজ্ঞায়িত নাম, অবশ্যই, ইতিমধ্যে সেখানে আছে। বেন চেরি

এর মানে এই যে কোড:

functionOne();                  ---------------      var functionOne;
                                | is actually |      functionOne();
var functionOne = function(){   | interpreted |-->
};                              |    like     |      functionOne = function(){
                                ---------------      };

ঘোষণা করুন যে ঘোষণার বরাদ্দ অংশটি উত্তোলন করা হয়নি। শুধুমাত্র নাম উত্তোলন করা হয়।

কিন্তু ফাংশন ঘোষণা সঙ্গে ক্ষেত্রে, পুরো ফাংশন শরীর এছাড়াও উত্তোলন করা হবে :

functionTwo();              ---------------      function functionTwo() {
                            | is actually |      };
function functionTwo() {    | interpreted |-->
}                           |    like     |      functionTwo();
                            ---------------

গ্রেগের উত্তর যথেষ্ট ভাল, তবে আমি এখনও কিছু যোগ করতে চাই যা আমি এখন ডগলাস ক্রকফোর্ডের ভিডিওগুলি দেখে শিখেছি ।

ফাংশন এক্সপ্রেশন:

var foo = function foo() {};

ফাংশন বিবৃতি:

function foo() {};

ফাংশন বিবৃতি varএকটি functionমান সঙ্গে বিবৃতি জন্য একটি শর্ট্যান্ড ।

সুতরাং

function foo() {};

প্রসারিত

var foo = function foo() {};

যা আরও প্রসারিত:

var foo = undefined;
foo = function foo() {};

এবং তারা উভয় কোড শীর্ষে hoisted হয়।


তারা কিছু ছোট পার্থক্যগুলির সাথে খুব সাদৃশ্যপূর্ণ, প্রথমটি একটি পরিবর্তনশীল যা একটি বেনামী ফাংশন (ফাংশন ঘোষণা) এ নির্ধারিত হয় এবং দ্বিতীয়টি জাভাস্ক্রিপ্ট (বেনামী ফাংশন ঘোষণা) তে একটি ফাংশন তৈরি করার স্বাভাবিক উপায়, উভয়ই ব্যবহার, :

1. ফাংশন এক্সপ্রেশন

var functionOne = function() {
    // Some code
};

একটি ফাংশন এক্সপ্রেশন একটি ফাংশনকে একটি বৃহত্তর অভিব্যক্তি সিনট্যাক্স (সাধারণত একটি পরিবর্তনশীল অ্যাসাইনমেন্ট) অংশ হিসাবে সংজ্ঞায়িত করে। ফাংশন এক্সপ্রেশন মাধ্যমে সংজ্ঞায়িত ফাংশন নাম বা বেনামী করা যেতে পারে। ফাংশন এক্সপ্রেশনগুলি অবশ্যই "ফাংশন" দিয়ে শুরু করা উচিত নয় (অতএব নিচের স্বচালিত উদাহরণের চারপাশে বন্ধনী)।

একটি ফাংশনে একটি ভেরিয়েবল বরাদ্দ করুন, কোন Hoisting মানে, আমরা জাভাস্ক্রিপ্ট মধ্যে ফাংশন Hoist করতে পারেন জানি, মানে তারা ঘোষিত করার আগে তাদের বলা যেতে পারে, যখন ভেরিয়েবল তাদের অ্যাক্সেস পাওয়ার আগে ঘোষণা করা প্রয়োজন, তাই এই ক্ষেত্রে আমরা বলতে পারি না ঘোষিত হওয়ার আগে ফাংশনটি অ্যাক্সেস করুন, এটি এমন একটি উপায় হতে পারে যা আপনি আপনার ফাংশন লিখতে পারেন, যে ফাংশনগুলি অন্য ফাংশনটি ফেরত দেয় সেগুলির জন্য, এই ধরনের ঘোষণাটি ইসিএম 6 এবং এর উপরেও বোঝা যায়, এটি একটি তীর ফাংশনে আপনাকে বরাদ্দ করতে পারে বেনামী ফাংশন কল করতে ব্যবহার করা যেতে পারে, জাভাস্ক্রিপ্টে কনস্ট্রাক্টর ফাংশন তৈরি করার আরও একটি ভাল উপায় ঘোষণা করার উপায়।

2. ফাংশন ঘোষণা

function functionTwo() {
    // Some code
}

একটি ফাংশন ঘোষণাপত্র পরিবর্তনশীল নিয়োগ প্রয়োজন ছাড়া একটি নামযুক্ত ফাংশন পরিবর্তনশীল সংজ্ঞায়িত করে। ফাংশন ঘোষণা স্বতন্ত্র গঠন হিসাবে সংঘটিত হয় এবং অ ফাংশন ব্লক মধ্যে নিস্তেজ করা যাবে না। ভেরিয়েবল ঘোষণাপত্রের ভাইবোন হিসাবে তাদের চিন্তা করা সহায়ক। ভেরিয়েবল ঘোষণাগুলি অবশ্যই "var" দিয়ে শুরু করতে হবে, ফাংশন ঘোষণাগুলি "ফাংশন" দিয়ে শুরু হওয়া আবশ্যক।

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

এছাড়াও, যদি জাভাস্ক্রিপ্টে কীভাবে উত্তোলন কাজ করে সে সম্পর্কে আরও তথ্যের প্রয়োজন হয় তবে নীচের লিঙ্কটিতে যান:

https://developer.mozilla.org/en-US/docs/Glossary/Hoisting


নীচের তালিকাভুক্ত দুটি ভিন্ন ঘোষণাগুলির মধ্যে তিনটি উল্লেখযোগ্য তুলনা রয়েছে।

  1. ফাংশন প্রাপ্যতা (সুযোগ)

নিচের function add()ব্লকটিকে স্কোপ করা হয়েছে বলে নিম্নলিখিত কাজগুলি :

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

function add(a, b){
  return a + b;
}

নিম্নলিখিত কাজ করে না (কারণ var add=superseeds function add())।

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function add(a, b){
  return a + b;
}

addএটি ব্যবহার করা হয় পরে ঘোষণা করা হয় নিম্নলিখিত নিম্নলিখিত কাজ করে না ।

try {
  console.log("Success: ", add(1, 1));
} catch(e) {
  console.log("ERROR: " + e);
}

var add=function(a, b){
  return a + b;
}

  1. (ফাংশন) .name

একটি ফাংশন নাম function thefuncname(){}হয় thefuncname যখন এই ভাবে ঘোষিত হয়।

function foobar(a, b){}

console.log(foobar.name);

var a = function foobar(){};

console.log(a.name);

অন্যথায়, যদি কোন ফাংশনটি ফাংশন হিসাবে ঘোষণা করা হয় function(){}, তবে ফাংশনটি সংরক্ষণ করতে ব্যবহৃত নাম।

var a = function(){};
var b = (function(){ return function(){} });

console.log(a.name);
console.log(b.name);

যদি ফাংশনে কোনও ভেরিয়েবল সেট থাকে তবে ফাংশন নাম খালি স্ট্রিং ( "")।

console.log((function(){}).name === "");

অবশেষে, যখন পরিবর্তনশীল ফাংশনটি প্রাথমিকভাবে নামটি সেট করে দেওয়া হয়, তখন ফাংশনে সেট করা ক্রমিক ভেরিয়েবলগুলি নামটি পরিবর্তন করে না।

var a = function(){};
var b = a;
var c = b;

console.log(a.name);
console.log(b.name);
console.log(c.name);

  1. কর্মক্ষমতা

গুগল এর ভি 8 এবং ফায়ারফক্সের স্পিডার্মোকিতে কিছু মাইক্রোসেকেন্ড জিআইএসটি সংকলন পার্থক্য থাকতে পারে, তবে অবশেষে ফলাফলটি একই রকম। এটি প্রমাণ করার জন্য, দুটি ফাঁকা কোড স্নিপেটের গতি তুলনা করে মাইক্রোবিনচার্কগুলিতে জেএসপিআরএফের দক্ষতা পরীক্ষা করে দেখুন। JSPerf পরীক্ষার এখানে পাওয়া যায় । এবং, jsben.ch testare এখানে পাওয়া যায় । আপনি দেখতে পারেন, যখন কেউ হতে হবে একটি উল্লেখযোগ্য পার্থক্য আছে। আপনি যদি সত্যিই আমার মত একটি পারফরম্যান্স ফিকাক হন, তবে সুযোগের ভেরিয়েবল এবং ফাংশন সংখ্যা এবং বিশেষত পলিমোরফিজম (যেমন একই ভেরিয়েবলটি দুটি ভিন্ন ধরণের সঞ্চয় করার জন্য) ব্যবহার করা কমিয়ে দেওয়ার চেষ্টা করা আপনার পক্ষে আরো মূল্যবান হতে পারে।

"নিকটতম ব্লক" কি

"নিকটতম ব্লক" নিকটতম "ফাংশন" (অ্যাসিঙ্ক্রোনাস ফাংশন, জেনারেটর ফাংশন এবং অ্যাসিঙ্ক্রোনাস জেনারেটরের ফাংশন সহ)। যাইহোক, মজার ব্যাপার, একটি function functionName() {}নিষ্ক্রিয় var functionName = function() {}ব্লক আইটেম বন্ধ যখন বলেন মত আচরণ । কর।

  • সাধারণ var add=function(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}');
  }
} catch(e) {
  console.log("Is a block");
}
var add=function(a, b){return a + b}

  • সাধারণ function add(){}

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
function add(a, b){
  return a + b;
}

  • ক্রিয়া

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(function () {
    function add(a, b){
      return a + b;
    }
})();

  • বিবৃতি (যেমন if, else, for, while, try/ catch/ finally, switch, do/ while, with)

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
{
    function add(a, b){
      return a + b;
    }
}

  • সঙ্গে তীর ফাংশন var add=function()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    var add=function(a, b){
      return a + b;
    }
})();

  • সঙ্গে তীর ফাংশন function add()

try {
  // typeof will simply return "undefined" if the variable does not exist
  if (typeof add !== "undefined") {
    add(1, 1); // just to prove it
    console.log("Not a block");
  }else if(add===undefined){ // this throws an exception if add doesn't exist
    console.log('Behaves like var add=function(a,b){return a+b}')
  }
} catch(e) {
  console.log("Is a block");
}
(() => {
    function add(a, b){
      return a + b;
    }
})();


প্রথম এক (ফাংশন do Somethingthing (x)) একটি বস্তু সংকেত অংশ হতে হবে।

দ্বিতীয়টি ( var doSomething = function(x){ alert(x);}) কেবল একটি বেনামী ফাংশন তৈরি করছে এবং এটি একটি পরিবর্তনশীলকে বরাদ্দ করছে doSomething। সুতরাং doSomething () ফাংশন কল করবে।

আপনি একটি ফাংশন ঘোষণা এবং ফাংশন অভিব্যক্তি কি জানতে চান হতে পারে ।

একটি ফাংশন ঘোষণা পরিবর্তনশীল নিয়োগ প্রয়োজন ছাড়া একটি নামযুক্ত ফাংশন পরিবর্তনশীল সংজ্ঞায়িত করে। ফাংশন ঘোষণা স্বতন্ত্র গঠন হিসাবে ঘটে এবং অ ফাংশন ব্লক মধ্যে নিস্তেজ করা যাবে না।

function foo() {
    return 3;
}

ইসিএমএ 5 (13.0)
ফাংশন আইডেন্টিফায়ার হিসাবে ফরম্যাট সংজ্ঞায়িত করে (ফরমালপ্যারিটারলিস্ট অপ্ট ) {FunctionBody}

উপরের অবস্থানে ফাংশন নামটি তার সুযোগ এবং তার পিতামাতার সুযোগের মধ্যে দৃশ্যমান (অন্যথায় এটি অ্যাক্সেসযোগ্য হবে)।

এবং একটি ফাংশন অভিব্যক্তি

একটি ফাংশন অভিব্যক্তি একটি বৃহত্তর অভিব্যক্তি সিনট্যাক্স (সাধারণত একটি পরিবর্তনশীল অ্যাসাইনমেন্ট) অংশ হিসাবে একটি ফাংশন সংজ্ঞায়িত করে। ফাংশন এক্সপ্রেশন মাধ্যমে সংজ্ঞায়িত ফাংশন নাম বা বেনামী করা যেতে পারে। ফাংশন এক্সপ্রেশন "ফাংশন" সঙ্গে শুরু করা উচিত নয়।

// Anonymous function expression
var a = function() {
    return 3;
}

// Named function expression
var a = function foo() {
    return 3;
}

// Self-invoking function expression
(function foo() {
    alert("hello!");
})();

ECMA 5 (13.0) সিন্ট্যাক্সটিকে
ফাংশন আইডেন্টিফায়ার অপ্ট (ফরমাল প্যারামিটারলিস্ট অপ্ট ) হিসাবে বর্ণনা করে {FunctionBody}


উভয় একটি ফাংশন সংজ্ঞায়িত বিভিন্ন উপায়। পার্থক্য হল কিভাবে ব্রাউজার ব্যাখ্যা করে এবং এটি একটি নির্বাহ প্রেক্ষাপটে লোড করে।

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

functionOne();
var functionOne = function() {
    // Some code
};

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

দ্বিতীয় লাইনে আমরা ফাংশনকে একটি বেনামী ফাংশনের রেফারেন্স বরাদ্দ করছি।

দ্বিতীয় ক্ষেত্রে ফাংশন ঘোষণা যে কোন কোড কার্যকর করা হয় আগে লোড হয়। সুতরাং যদি আপনি নিম্নলিখিতটি পছন্দ করেন তবে কোড এক্সিকিউশন আগে ঘোষণা লোড হিসাবে আপনি কোন ত্রুটি পাবেন না।

functionOne();
function functionOne() {
   // Some code
}




idioms