Eval () এবং নতুন ফাংশন () একই জিনিস?


92

এই দুটি ফাংশন কি পর্দার আড়ালে একই কাজ করছে? (একক বিবৃতি ফাংশন)

var evaluate = function(string) {
    return eval('(' + string + ')');
}

var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));

4
বাস্তবে এটি jQuery 1.7.2 লাইন 573 এ ব্যবহৃত হয়। যদিও "কিছু সুরক্ষা চেক" রয়েছে
পিকোক্রিটর

4
কেন newএই আলোচনায় বিবেচনা করা হয়? Functionসুস্পষ্টভাবে তাত্ক্ষণিকভাবে ক function object। বাদ দিলে newকোড মোটেও বদলাবে না। এখানে একটি জিসফিল প্রদর্শন করছে যে: jsfiddle.net/PcfG8
ট্র্যাভিস জে

উত্তর:


117

না, তারা এক নয়

  • eval() বর্তমান প্রয়োগের স্কোপের মধ্যে একটি জাভাস্ক্রিপ্ট এক্সপ্রেশন হিসাবে একটি স্ট্রিং মূল্যায়ন করে এবং স্থানীয় ভেরিয়েবল অ্যাক্সেস করতে পারে।
  • new Function()স্ট্রিংয়ে থাকা জাভাস্ক্রিপ্ট কোডটিকে কোনও ফাংশন অবজেক্টে পার্স করে, যা পরে বলা যেতে পারে। এটি স্থানীয় ভেরিয়েবল অ্যাক্সেস করতে পারে না কারণ কোডটি একটি পৃথক স্কোপে চলে।

এই কোডটি বিবেচনা করুন:

function test1() {
    var a = 11;
    eval('(a = 22)');
    alert(a);            // alerts 22
}

যদি new Function('return (a = 22);')()ব্যবহার করা হয় তবে স্থানীয় ভেরিয়েবল aএর মান ধরে রাখতে পারে। তবুও, কিছু জাভাস্ক্রিপ্ট প্রোগ্রামার যেমন ডগলাস ক্রকফোর্ড বিশ্বাস করেন যে একেবারে প্রয়োজনীয় না হলে উভয়ই ব্যবহার করা উচিত নয় , এবং অবিশ্বস্ত ডেটাতে কনস্ট্রাক্টরকে বিলোপ করা / ব্যবহার করা নিরাপত্তাহীন এবং বুদ্ধিমানের নয় ।Function


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

4
@ জুয়ান: ক্রকফোর্ডের বক্তব্যটি হ'ল ইওল প্রায়শই অপব্যবহার করা হয় (আপনার দৃষ্টিভঙ্গির উপর নির্ভর করে), সুতরাং এটি একটি "সেরা অনুশীলন" জাভাস্ক্রিপ্ট থেকে বাদ দেওয়া উচিত। তবে আমি সম্মত হই না যে ইনপুট প্রথমে সঠিকভাবে যাচাই করা হলে এটি JSON বা পাটিগণিতের এক্সপ্রেশন পার্সিংয়ের মতো ব্যবহারের জন্য কার্যকর। এমনকি ক্রকফোর্ড এটি তার JSON লাইব্রেরি json2.js এ ব্যবহার করে।
দয়া

সুতরাং এর অর্থ new Function(code)কি এটি একই eval('(function(){'+code+'})()')বা এটি সম্পূর্ণ নতুন বাস্তবায়ন প্রসঙ্গে?
জর্জ মাউর

4
@ জর্জিমৌয়ার: আমার ধারণা আপনার অর্থ eval('(function(){'+code+'})'), যা কোনও ফাংশনটি ফেরত দেবে। এমডিএন-এর মতে , "ফাংশন কনস্ট্রাক্টরের সাথে তৈরি ফাংশনগুলি তাদের সৃষ্টি প্রসঙ্গে ক্লোজার তৈরি করে না; তারা সর্বদা উইন্ডো প্রসঙ্গে চালায় (যদি না ফাংশন বডিটি" কঠোর ব্যবহার "দিয়ে শুরু হয়; বিবৃতি, যার ক্ষেত্রে প্রসঙ্গটি অনির্ধারিত থাকে) "
অনুগ্রহ করে

6

না

আপনার আপডেট সালে কল evaluateএবং funcএকই ফলাফল উত্পাদন। তবে, তারা অবশ্যই "পর্দার পিছনে একই জিনিস করছেন" না। funcফাংশন একটি নতুন ফাংশন তৈরি করে, কিন্তু তারপর অবিলম্বে এটি executes, যেহেতু evaluateফাংশন কেবল ঘটনাস্থলেই কোড সঞ্চালন করে।

মূল প্রশ্ন থেকে:

var evaluate = function(string) {
    return eval(string);
}
var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

এগুলি আপনাকে খুব আলাদা ফলাফল দেবে:

evaluate('0) + (4');
func('0) + (4');

যাইহোক, উভয়ই সব ক্ষেত্রেই খারাপ অভ্যাস তবে সবচেয়ে ব্যতিক্রমী ক্ষেত্রে।
পালসুইম

8
ঠিক আছে আপনি তার বাস্তবায়ন অনুসারে আপনার উদাহরণটিকে প্রত্যাখ্যান করেছিলেন। তিনি যদি তখন মূল্যায়ন কার্যকর করেন return eval('(' + string + ')');তবে তারা একই ফলাফল অর্জন করবে।
হুয়ান মেন্ডেস

@ জুয়ান আমি হ্যাঁ ভেবে দেখিনি। প্রশ্নটি সম্পাদনা করা হয়েছে
কিওয়ারটিমক

6

new Function পুনরায় ব্যবহার করা যেতে পারে এমন একটি ফাংশন তৈরি করে। evalকেবলমাত্র প্রদত্ত স্ট্রিং কার্যকর করে শেষ বিবৃতিটির ফলাফল প্রদান করে। আপনার প্রশ্নটি বিপথগামী হয়ে গেছে আপনি যখন একটি মোড়ক ফাংশন তৈরি করার চেষ্টা করেছিলেন যা ফাংশনটিকে একটি emল অনুকরণ করতে ব্যবহার করে।

তারা কি পর্দার পিছনে কিছু কোড ভাগ করে নিচ্ছে তা সত্য? হ্যাঁ, খুব সম্ভবত ঠিক একই কোড? না, অবশ্যই।

মজাদার জন্য, এখানে একটি ক্রিয়াকলাপ তৈরি করার জন্য eval ব্যবহার করে আমার নিজের অসম্পূর্ণ বাস্তবায়ন। আশা করি এতে কিছুটা আলোকপাত হয়েছে!

function makeFunction() {
  var params = [];
  for (var i = 0; i < arguments.length -  1; i++) {
    params.push(arguments[i]);
  }
  var code = arguments[arguments.length -  1];


 // Creates the anonymous function to be returned
 // The following line doesn't work in IE
 // return eval('(function (' + params.join(',')+ '){' + code + '})');
 // This does though
 return eval('[function (' + params.join(',')+ '){' + code + '}][0]');
}

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


কেন arguments.slice()লুপের পরিবর্তে ব্যবহার করবেন না? অথবা যদি তর্কগুলি সত্যিকারের অ্যারে না হয় [].slice.call(arguments, 1),।
এক্সনক্রস

3

এখানে উদাহরণগুলিতে ব্যবহৃত কিছু বাক্য গঠন এবং এর অর্থ কী তা বোঝাতে চাই:

 var func = function(string) {
     return (new Function( 'return (' + string + ')' )());
 }

লক্ষ্য করুন যে ফাংশনটির (...) () শেষে "()" রয়েছে। এই বাক্য গঠনটি ফানুকে নতুন ফাংশনটি কার্যকর করতে এবং স্ট্রিংটিকে কোনও ফাংশন নয় যা স্ট্রিং ফিরিয়ে দেয়, তবে আপনি যদি নিম্নলিখিতটি ব্যবহার করেন:

 var func = function(string) {
     return (new Function( 'return (' + string + ')' ));
 }

এখন ফানক একটি ফাংশন ফিরিয়ে দেবে যা একটি স্ট্রিং দেয়।


2

যদি আপনি বোঝাতে চান, এটি কি একই ফলাফল দেয়, তবে হ্যাঁ ... তবে কেবল প্রমাণ করতে (ওরফে, "জাভাস্ক্রিপ্টের এই স্ট্রিংটি মূল্যায়ন করুন") অনেক সহজ হবে।

নীচে সম্পাদনা করুন:

এটি বলার মতো ... এই দুটি গণিত সমস্যা কি একই:

1 + 1

1 + 1 + 1 - 1 + 1 - 1 * 1/1


তারা উভয় স্ট্রিং পুনরায় পার্স করে?
কিওয়ারটাইমক

তারা উভয় স্ট্রিংকে পার্স করবে (আপনার কোড উদাহরণে)। "রি-পার্স" বলতে কী বোঝেন তা জানেন না।
টিমোথি খৌরি

4
আমি নিশ্চিত যে তারা উভয়ই কোনও সময়ে স্ট্রিংকে পার্স (মূল্যায়ন) করে তবে এটি Function আপনি evalযখন ফাংশনটি চালু করবেন তখন অবজেক্টটি সম্ভবত একটি ব্যক্তিগত সদস্যের পরিবর্তনশীলতে স্ট্রিংটি সঞ্চয় করে ।
পালসুইম

1

এই উদাহরণে, ফলাফলগুলি একই, হ্যাঁ। উভয়ই আপনি যে অভিব্যক্তিটি পাস করেছেন তা কার্যকর করে। এটি তাদের এত বিপজ্জনক করে তোলে।

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

আপনি এতে যে জাভাস্ক্রিপ্টটি পাস করেছেন তা প্রযুক্তিগতভাবে কার্যকর করা হবে না যতক্ষণ না আপনি বেনাম ফাংশনটি না চান। এটি এর বিপরীতে eval()যা এই মুহুর্তে কোডটি কার্যকর করে এবং এর উপর ভিত্তি করে কোনও ফাংশন তৈরি করে না।


আপনি কি আরও কিছু ব্যাখ্যা করতে পারেন? তারা দুজনেই কি রিটার্নের বিবৃতিতে মৃত্যুদণ্ড কার্যকর করা হয়নি? ফাংশন () একের সাথে কি অন্যটি স্ট্যাক কল স্তরটি স্পষ্টভাবে ব্যবহৃত হয়?
কিওয়ারটাইমক

Does the Function() one use another stack call level than eval?: আমি অনুমান করব, কারণ eval()আপনার ইনপুট থেকে কোনও ফাংশন তৈরি করে না - এটি কেবল এটি কার্যকর করে। new Function()একটি নতুন ফাংশন তৈরি করে, যা এটি পরে অনুরোধ করে।
ক্রিস ল্যাপ্লেন্ট

@ সিম্পলকোডার: ফাংশন () কল স্ট্যাকটিতে কোনও কিছুই যুক্ত করে না। আপনি যদি ফলাফলের ফাংশনটি কল করেন তবেই। eval ঠিক একই জিনিসটি (যদি প্রশ্নটির প্রসঙ্গে প্রয়োগ হয়)
হুয়ান মেন্ডেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.