আপনি কি একটি তীর ফাংশন 'এটি' বাঁধতে পারেন?


133

আমি এখন কিছুক্ষণ ES6 নিয়ে পরীক্ষা-নিরীক্ষা করছি এবং আমি কিছুটা সমস্যা নিয়ে এসেছি।

আমি সত্যই তীর ফাংশনগুলি ব্যবহার করতে পছন্দ করি এবং যখনই আমি পারি তখন আমি সেগুলি ব্যবহার করি।

তবে, এটি প্রদর্শিত হবে যে আপনি এগুলি আবদ্ধ করতে পারবেন না!

ফাংশনটি এখানে:

var f = () => console.log(this);

ফাংশনটি এখানে আবদ্ধ করতে চান সেই অবজেক্টটি এখানে:

var o = {'a': 42};

এবং এখানে আমি বাঁধে হবে fথেকে o:

var fBound = f.bind(o);

এবং তারপরে আমি কেবল কল করতে পারি fBound:

fBound();

যা এটি ( oঅবজেক্ট) আউটপুট দেবে :

{'a': 42}

শান্ত! বাহ! ব্যতীত এটি কাজ করে না। Outputting পরিবর্তে oবস্তু, আউটপুট windowঅবজেক্ট।

সুতরাং আমি জানতে চাই: আপনি তীর ফাংশন বাঁধতে পারেন? (এবং যদি তা হয় তবে কিভাবে?)


আমি গুগল ক্রোম 48 এবং ফায়ারফক্স 43 এ উপরের কোডটি পরীক্ষা করেছি এবং ফলাফলটি একই is


29
তীর ফাংশনগুলির সম্পূর্ণ বিন্দুটি হ'ল তারা thisতাদের পিতামাতার সুযোগটি ব্যবহার করে ।
লগানফস্মিথ

উত্তর:


158

আপনি কোনও তীর ফাংশনটিতে পুনঃতফসিল করতে পারবেন না this। এটি সর্বদা প্রসঙ্গ হিসাবে সংজ্ঞায়িত করা হবে হিসাবে সংজ্ঞায়িত হবে। আপনার যদি thisঅর্থবহ হতে হয় তবে আপনার একটি সাধারণ ক্রিয়া ব্যবহার করা উচিত।

থেকে এর নাম ECMAScript 2015 ফটকা খেলা :

একটি তীর ফাংশন এর মধ্যে আর্গুমেন্ট, সুপার, এটি, বা নতুন ডটারের কোনও রেফারেন্সের একটি লেক্সিক্যালি এনক্লোজিং পরিবেশে বাঁধার সমাধান করতে হবে। সাধারণত এটি তাত্ক্ষণিকভাবে বন্ধ করা ফাংশনের ফাংশন পরিবেশ হবে।


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

54

সম্পূর্ণ হবে, আপনি করতে পারেন পুনরায় বেঁধে তীর ফাংশন, আপনি শুধু অর্থ পরিবর্তন করতে পারবেন না this

bind এখনও ফাংশন আর্গুমেন্ট জন্য মান আছে:

((a, b, c) => {
  console.info(a, b, c) // 1, 2, 3
}).bind(undefined, 1, 2, 3)()

এটি এখানে চেষ্টা করুন: http://jsbin.com/motihanopi/edit?js,console


1
কোনও রেফারেন্স ছাড়াই this(যা অবশ্যই, সংক্ষিপ্তভাবে সংজ্ঞায়িত করা হয়েছে) বিন্যাস ছাড়াই (তীর) ফাংশনটির সাথে আবদ্ধ যেকোন অবজেক্টটি সনাক্ত বা ব্যবহার করার কোনও উপায় আছে ?
ফ্লোরি

3
((প্রসঙ্গ) => {someOtherFunction.apply (প্রসঙ্গ)}) বেঁধে (willBeIgnored, প্রসঙ্গ) (।): প্রসঙ্গ জন্য একটি আর্গুমেন্ট ব্যবহার করুন
cvazac

13

এমডিএন থেকে :

একটি তীর ফাংশন এক্সপ্রেশন ফাংশন এক্সপ্রেশনগুলির তুলনায় একটি সংক্ষিপ্ত বাক্য গঠন করে এবং বর্ণটি এই মানটিকে সংক্ষিপ্ত করে তোলে (এর নিজস্ব এটি, যুক্তি, সুপার বা new.target আবদ্ধ করে না)। তীর ফাংশন সবসময় বেনামে থাকে।

এর অর্থ আপনি নিজের thisপছন্দ মত মান বেঁধে রাখতে পারবেন না ।


6

বছরের পর বছর ধরে, জেএস বিকাশকারীরা প্রসঙ্গ বাঁধাইয়ের সাথে লড়াই করে, thisজাভাস্ক্রিপ্টে কেন পরিবর্তন হয়েছে জানতে চেয়েছিলেন, প্রসঙ্গ বাঁধার কারণে thisএবং জাভাস্ক্রিপ্টে এবং thisঅন্যান্য বেশিরভাগ ওওপি ভাষার বেশিরভাগের মধ্যে পার্থক্যের কারণে এত বিভ্রান্তি রয়েছে ।

এই সব আমাকে জিজ্ঞাসা করে, কেন, কেন! আপনি কেন একটি তীর ফাংশন রিইন্ড করতে চান না! যারা এই সমস্ত সমস্যা এবং বিভ্রান্তি সমাধানের জন্য বিশেষভাবে তৈরি করেছেন এবং ফাংশনটির ব্যাপ্তি সংরক্ষণের জন্য ব্যবহার করা bindবা callঅন্য যে কোনও উপায়ে ব্যবহার করা এড়াতে চান ।

টি এল; ডিআর

না, আপনি তীর ফাংশনগুলি পুনরায় ফিরিয়ে দিতে পারবেন না।


7
একটি ক্লিনার এবং দ্রুত সিনট্যাক্স সরবরাহ করতে সবার আগে তীরের ক্রিয়া তৈরি করা হয়েছিল। ল্যাম্বদা-ক্যালকুলাস ভাবুন। কার্যকরী জেএস প্রোগ্রামারদের জীবনকে বেঁধে দেওয়া ওও-জেওলোটগুলি খুব খারাপ, অনুরোধ প্রসঙ্গে নির্দিষ্ট করার স্বাধীনতা কেড়ে নেওয়ার সুযোগটি হাতছাড়া করে।
মার্কো ফাউস্টিনেলি

5
ব্যবহার thisকার্যকরী নয়। ল্যাম্বডাস হওয়া উচিত arguments => output। আপনার যদি কিছু বাহ্যিক প্রসঙ্গের প্রয়োজন হয় তবে এটিকে পাস thisকরুন O এর অস্তিত্বই হ'ল ভাষাতে ওও নিদর্শনগুলির সমস্ত জুতো প্রবাহকে সহজতর করে। আপনি এটি "জাভাস্ক্রিপ্ট শ্রেণি" শব্দটি কখনও শুনেন নি।
erich2k8

3
আপনি তীর ফাংশনগুলি পুনরায় ফিরিয়ে আনতে পারেন । ঠিক না this
স্টিজন ডি উইট

6

আপনি একটি তীর ফাংশনের অভ্যন্তরের bindমান পরিবর্তন করতে ব্যবহার করতে পারবেন না this। তবে, আপনি একটি নতুন নিয়মিত ফাংশন তৈরি করতে পারেন যা পুরানো তীর ফাংশনটির মতো একই কাজ করে এবং তারপরে ব্যবহার করুন callবা যথারীতি bindপুনরায় বাঁধাই করতে পারেন this

আপনি evalএখানে একটি কলটি ব্যবহার করেন যা আপনি সাধারণ ক্রিয়াকলাপ হিসাবে পাস করেন এমন তীর ফাংশনটি পুনরায় তৈরি করতে এবং তারপরে callএটির সাথে অন্যরকম প্রার্থনা করতে ব্যবহার করুন this:

var obj = {value: 10};
function arrowBind(context, fn) {
  let arrowFn;
  (function() {
    arrowFn = eval(fn.toString());
    arrowFn();
  }).call(context);
}
arrowBind(obj, () => {console.log(this)});


3
একটি তীর ফাংশনকে অন্য প্রসঙ্গে আবদ্ধ করার একটি উপায় উদাহরণটি ভাগ করে নেওয়ার জন্য আপনাকে ধন্যবাদ! উত্তরটি ভবিষ্যতের পাঠকদের বোঝার পক্ষে সহজ করার জন্য, কোডটি কীভাবে এবং কেন কাজ করে তা বর্ণনা করার জন্য আপনি সম্ভবত এটি সম্পাদনা করতে পারেন?
ফ্লোরি

4

ES6 তীর ফাংশনগুলি সত্যিই জাভাস্ক্রিপ্টে "এটি" সমাধান করুন

উপরের লিঙ্কটি ব্যাখ্যা করে যে তীর ফাংশনগুলি ফাংশনগুলির thisসাথে পরিবর্তন হয় না bind, call, apply

এটি খুব সুন্দর উদাহরণ দিয়ে ব্যাখ্যা করা হয়েছে।

node v4"প্রত্যাশিত" আচরণ দেখতে এটি চালান ,

this.test = "attached to the module";
var foo = { test: "attached to an object" };
foo.method = function(name, cb){ 
    // bind the value of "this" on the method 
    // to try and force it to be what you want 
    this[name] = cb.bind(this); };
foo.method("bar", () => { console.log(this.test); });
foo.bar(); 

উত্তরে নিজেই আরও প্রাসঙ্গিক তথ্য সরবরাহ করার অনুরোধ করুন, একটি নমুনা কোড বা প্রশ্নের সম্পাদিত সংস্করণ হতে পারে
Jithin Scaria

// "প্রত্যাশিত" আচরণটি দেখতে নোড ভি 4 এ এটি চালান এই টেস্ট = "মডিউলের সাথে সংযুক্ত"; var foo = {পরীক্ষা: "একটি বস্তুর সাথে সংযুক্ত"}; foo.method = ফাংশন (নাম, সিবি) {// পদ্ধতিতে "এই" এর মানটি বাঁধুন // চেষ্টা করুন এবং আপনি এটি চান তা হতে বাধ্য করুন [নাম] = সিবি.বাইন্ড (এটি); }; foo.method ("বার", () => so কনসোল.লগ (এটি.পরে);}); foo.bar ();
পৃথ্বী রাজ ভুপ্পলপতি

এখানে আকর্ষণীয় হ'ল এটি চেষ্টা করা এবং তারপরে foo.method ('বার', () => {কনসোল.লগ (এটি.পরে);}) প্রতিস্থাপনের চেষ্টা করে আবার চেষ্টা করুন; foo.method ('বার', ফাংশন () {কনসোল.লগ (এটি.পরে);}) সহ; - প্রথম সংস্করণ লগগুলি "মডিউলটির সাথে সংযুক্ত" এবং দ্বিতীয় লগগুলি "কোনও বস্তুর সাথে সংযুক্ত" - আমি সত্যই তীর ফাংশন ব্যবহার করে "এটি" এর আরও স্থিতিশীল চিকিত্সা পছন্দ করি। আপনি এখনও বিভিন্ন নিদর্শন ব্যবহার করে অন্যান্য প্রভাবগুলি অর্জন করতে পারেন এবং ফলাফলগুলি আরও পঠনযোগ্য এবং অনুমানযোগ্য আইএমও are
মেথোডিশিয়ান

3

কয়েক দিন আগেও আমি একই প্রশ্ন করেছি।

thisইতিমধ্যে আবদ্ধ হওয়ার কারণে আপনি কোনও মান বাঁধতে পারবেন না ।

এই সুযোগটি ES6 => ফাংশন অপারেটরের সাথে পৃথক করে বাঁধাই


4
"যেহেতু এটি ইতিমধ্যে thisআবদ্ধ " - নিয়মিত ফাংশনগুলিতে খুব আবদ্ধ। মুল বক্তব্যটি হ'ল তীর ফাংশনে এটির কোনও স্থানীয় বাঁধাই নেই।
আরও ভাল অলিভার

2

সংক্ষিপ্ত, আপনি তীর ফাংশন বাঁধতে পারবেন না তবে এতে পড়ুন:

কল্পনা করুন আপনার নীচে এই তীর ফাংশন রয়েছে যার নীচে thisকনসোলে মুদ্রণ রয়েছে:

const myFunc = ()=> console.log(this);

সুতরাং এটির দ্রুত সমাধানটি সাধারণ ফাংশনটি ব্যবহার করবে, সুতরাং কেবল এটিকে পরিবর্তন করুন:

function myFunc() {console.log(this)};

তারপর আপনি ব্যবহার করে যে কোনও আভিধানিক পরিবেশ এটা আবদ্ধ করতে পারেন bindবা callবা apply:

const bindedFunc = myFunc.bind(this);

এবং ক্ষেত্রে এটি কল bind

bindedFunc();

এটি করার বিভিন্ন উপায় রয়েছে eval()যা দৃ which়ভাবে সুপারিশ করা হয় না


function myFuncবাধ্যবাধকতা ছাড়াও আচরণগতভাবে বিভিন্নভাবে পৃথক; একটি কাছাকাছি ম্যাচ হবে const myFunc = function() {...}। আপনি কীভাবে ইওল ব্যবহার করে বোঝাতে চেয়েছেন তা জানতে আগ্রহী, যেহেতু এটি এমন একটি পদ্ধতির যা আমি মনে করি না যে এর আগে কোনও উত্তর এখানে ভাগ করে নিয়েছে - এটি কীভাবে হয়েছে তা দেখার জন্য আকর্ষণীয় হবে এবং তারপরে পড়ুন কেন এটি এত দৃ strongly়ভাবে নিরুৎসাহিত হয়েছে।
ফ্লোরি

1

এই উদাহরণটি আপনাকে সাহায্য করতে পারে:

let bob = {
   _name: "Bob",
   _friends: ["stackoverflow"],
   printFriends:(x)=> {
      x._friends.forEach((f)=> {
         console.log(x._name + " knows " + f);
      });
   }
}

bob.printFriends = (bob.printFriends).bind(null,bob);
bob.printFriends();


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