ভার স্ব = এই?


182

উদাহরণ হিসেবে বলা যায় পদ্ধতি ব্যবহার ইভেন্ট হ্যান্ডলার জন্য callbacks পরিধি পরিবর্তন thisথেকে "আমার উদাহরণস্বরূপ" থেকে "যাই শুধু কলব্যাক নামক" । সুতরাং আমার কোড এর মত দেখাচ্ছে

function MyObject() {
  this.doSomething = function() {
    ...
  }

  var self = this
  $('#foobar').bind('click', function(){
    self.doSomethng()
    // this.doSomething() would not work here
  })
}

এটি কাজ করে, তবে এটি করার সর্বোত্তম উপায়? এটি আমার কাছে অদ্ভুত লাগছে।


15
selfকোনও window.selfবিষয় আছে বলে আপনার এড়ানো উচিত এবং যদি আপনি নিজের selfভেরি ঘোষণা করতে ভুলে যান (উদাহরণস্বরূপ কিছু কোড ঘোরার সময়) আপনি দুর্ঘটনাক্রমে এটি ব্যবহার করতে পারেন । এটি স্পট / ডিবাগের জন্য বিরক্তিকর হতে পারে। এর মতো কিছু ব্যবহার করা ভাল _this
অ্যালাস্টার মাউ


3
থেকে জাভাস্ক্রিপ্ট টিউটোরিয়াল : "এর মান thisজাভাস্ক্রিপ্ট গতিশীল, বরং এটি নির্ধারিত হয় যখন ফাংশন। নামক যখন এটা ঘোষিত হয়।"
ডেভিডআরআর


বিষয়টি হ'ল বিশ্বব্যাপী self === this। অতএব, selfস্থানীয় প্রেক্ষাপটে বোঝা যায় এবং প্যাটার্ন অনুসরণ করে।
programmer5000

উত্তর:


210

এই প্রশ্নটি jQuery এর জন্য নির্দিষ্ট নয়, তবে সাধারণভাবে জাভাস্ক্রিপ্টের জন্য নির্দিষ্ট specific মূল সমস্যাটি হ'ল এমবেডড ফাংশনগুলিতে কোনও পরিবর্তনশীল "চ্যানেল" কীভাবে করা যায়। এটি উদাহরণ:

var abc = 1; // we want to use this variable in embedded functions

function xyz(){
  console.log(abc); // it is available here!
  function qwe(){
    console.log(abc); // it is available here too!
  }
  ...
};

এই কৌশলটি ক্লোজার ব্যবহারের উপর নির্ভর করে। তবে এটি এর সাথে কাজ করে না thisকারণ thisএকটি সিউডো ভেরিয়েবল যা স্কোপ থেকে স্কোপে পরিবর্তনশীল হতে পারে:

// we want to use "this" variable in embedded functions

function xyz(){
  // "this" is different here!
  console.log(this); // not what we wanted!
  function qwe(){
    // "this" is different here too!
    console.log(this); // not what we wanted!
  }
  ...
};

আমরা কি করতে পারি? এটি কিছু ভেরিয়েবলের জন্য বরাদ্দ করুন এবং উপনামের মাধ্যমে এটি ব্যবহার করুন:

var abc = this; // we want to use this variable in embedded functions

function xyz(){
  // "this" is different here! --- but we don't care!
  console.log(abc); // now it is the right object!
  function qwe(){
    // "this" is different here too! --- but we don't care!
    console.log(abc); // it is the right object here too!
  }
  ...
};

thisএই ক্ষেত্রে অনন্য নয়: argumentsঅন্য সিউডো ভেরিয়েবল যা একইভাবে আচরণ করা উচিত - আলিয়াজ করে।


7
আপনার সত্যিই "এটি" ফাংশন কলের সাথে আবদ্ধ করা উচিত এবং এটির চারপাশে বা এটির সাথে ভেরিয়েবল স্কোপগুলি পাস করা উচিত নয়
মাইকেল

10
@ মাইকেল কেন?
ক্রিস অ্যান্ডারসন

@ মাইকেল আপনি হয়ত পাইপ, মানচিত্র, সাবস্ক্রাইবগুলির ভিতরে ... একটি ফাংশনে কাজ করছেন এবং ফাংশনগুলি কল করছেন না, এই ক্ষেত্রে "এটি" পরিবর্তিত হচ্ছে, সুতরাং পরিবর্তনশীল সুযোগটি সমাধান
হ'ল

@ স্ক্যান্ডার জেনহানি যে মন্তব্যটি 8 বছর বয়সী। আমার উত্তরটি আজ খুব আলাদা হবে
মাইকেল 25

18

হ্যাঁ, এটি একটি সাধারণ মান বলে মনে হচ্ছে। কিছু কোডার স্ব ব্যবহার করে, অন্যরা আমাকে ব্যবহার করে। এটি ইভেন্টের বিপরীতে "রিয়েল" অবজেক্টের রেফারেন্স হিসাবে ব্যবহৃত হয়।

এটি এমন কিছু যা আমাকে পেতে সত্যিই কিছুটা সময় নিয়েছিল, এটি প্রথমে অদ্ভুত দেখাচ্ছে।

আমি সাধারণত আমার অবজেক্টের শীর্ষে এটি করি (আমার ডেমো কোডটি ক্ষমা করুন - এটি অন্য যে কোনও কিছুর চেয়ে ধারণাগত এবং সর্বোত্তম কোডিং কৌশলটির পাঠ নয়):

function MyObject(){
  var me = this;

  //Events
  Click = onClick; //Allows user to override onClick event with their own

  //Event Handlers
  onClick = function(args){
    me.MyProperty = args; //Reference me, referencing this refers to onClick
    ...
    //Do other stuff
  }
}

12
var functionX = function() {
  var self = this;
  var functionY = function(y) {
    // If we call "this" in here, we get a reference to functionY,
    // but if we call "self" (defined earlier), we get a reference to function X.
  }
}

সম্পাদনা: সত্ত্বেও, কোনও বস্তুর মধ্যে নেস্টেড ফাংশনগুলি আশেপাশের বস্তুর পরিবর্তে বিশ্বব্যাপী উইন্ডো অবজেক্টকে গ্রহণ করে।


আপনি কী করছেন var self = thisতার বর্ণনা দিচ্ছেন বলে মনে হচ্ছে , তবে প্রশ্নটি যা জিজ্ঞাসা করছে তা নয় (প্রশ্নটি যদি জিজ্ঞাসা করছে যে এটি সমস্যার সেরা সমাধান কিনা)।
কোয়ান্টিন

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

12

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

this.name = 'test'
myObject.doSomething(data => {
  console.log(this.name)  // this should print out 'test'
});

5
ব্যাখ্যা হিসাবে: ES2015 এ তীর ফাংশনগুলি thisতাদের সংজ্ঞায়িত সুযোগ থেকে ক্যাপচার করে । সাধারণ ফাংশন সংজ্ঞাগুলি তা করে না।
ডিফনুল

@ ডিফনুল আমি এটি বিশেষ কিছু মনে করি না। ক্রিয়াকলাপগুলি একটি ব্লক সুযোগ তৈরি করে। সুতরাং একটি ফাংশনের পরিবর্তে তীরচিহ্ন ব্যবহার করে আপনাকে সুযোগ তৈরি থেকে বিরত রাখে, সুতরাং এটি এখনও বহিরাগত এই পরিবর্তনশীলটিকে উল্লেখ করবে refer
নিমেশকা শ্রীমাল

4

এর একটি সমাধান হ'ল জাভাস্ক্রিপ্টের bindপদ্ধতির সাথে আপনার সমস্ত কলব্যাকটিকে আপনার অবজেক্টে আবদ্ধ করা ।

আপনি এটি একটি নামযুক্ত পদ্ধতিতে করতে পারেন,

function MyNamedMethod() {
  // You can now call methods on "this" here 
}

doCallBack(MyNamedMethod.bind(this)); 

বা বেনামে কলব্যাক সহ

doCallBack(function () {
  // You can now call methods on "this" here
}.bind(this));

এগুলি করার পরিবর্তে এগুলি করা আপনাকে var self = thisদেখায় যে thisজাভাস্ক্রিপ্টে বাঁধাই কীভাবে আচরণ করে এবং একটি ক্লোজার রেফারেন্সের উপর নির্ভর করে না।

এছাড়াও, ES6 এ ফ্যাট অ্যারো অপারেটর মূলত .bind(this)বেনামে ফাংশনটির জন্য একই কলিং :

doCallback( () => {
  // You can reference "this" here now
});

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

3

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

 $('#foobar').ready('click', this.doSomething.bind(this));

বাইন্ড পদ্ধতিটি একটি নতুন ফাংশন প্রদান করে যা আপনার নির্দিষ্ট সুযোগের সাথে মূল পদ্ধতিটিকে কল করে।


অনুরূপ: $('#foobar').ready('click', this.doSomething.call(this));ঠিক?
মুয়ার্স

bindপদ্ধতি পুরোনো ব্রাউজারে কাজ করে না, তাই ব্যবহার $.proxyপরিবর্তে পদ্ধতি।
গুফা


1

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

function doSomething(){
  .........
}

$("#foobar").ready('click', function(){

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