No need to declare "var me = this" for javascript prototype functions

I am currently creating objects in javascript by declaring a construct (regular function) and then adding methods to the prototype, for example:

function Test(){ } Test.prototype.test1 = function(){ var me = this; } 

However, I would like not to declare var me = this at the top of each function. The following seems to work, but it looks like it will be very inefficient:

 $(document).ready(function(){ var n = 0; (function(){ function createTest(){ var me; function Test(){ this.n = n; this.testArr = [1, 2, 3, 4]; n++; } Test.prototype.test1 = function(){ me.test2(); }; Test.prototype.test2 = function(){ alert(me.n); $.getJSON('test.php', {}, function(reply) //want to be able to use 'me' here me.newField = reply; }); }; var t = new Test(); me = t; return t; } window['createTest'] = createTest; })(); var t = createTest(); t.test1(); var t2 = createTest(); t2.test1(); t.test1(); }); 

This code prints the expected, but is it really inefficient how it looks (the Test object is re-declared each time you call createTest ())?

Anyhoo, that would seem a bit hacked ... is there a completely different way to do this, which is better?

EDIT: The real reason I would like to do this is because callbacks like the ones in test2 would have references to the correct this .

+4
source share
3 answers

What you can do is bind the current value of this to function and save a copy somewhere. (For the sake of efficiency.)

 if (!Function.prototype.bind) { // Most modern browsers will have this built-in but just in case. Function.prototype.bind = function (obj) { var slice = [].slice, args = slice.call(arguments, 1), self = this, nop = function () { }, bound = function () { return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments))); }; nop.prototype = self.prototype; bound.prototype = new nop(); return bound; }; } function Test(n) { this.n = n; this.callback = (function () { alert(this.n); }).bind(this) } Test.prototype.test1 = function () { this.test2(); } Test.prototype.test2 = function () { doSomething(this.callback); } function doSomething(callback) { callback(); } var t = new Test(2); t.test1(); 
+2
source

I understand that your question was not tagged with jQuery, but you are using it in your example, so my solution also uses jQuery.

I sometimes use the $.proxy function to avoid the callback context. Take a look at this simple jsfiddle example . Source below.

 function Test(){ this.bind(); } Test.prototype.bind = function(){ $('input').bind('change', $.proxy(this.change, this)); // you could use $.proxy on anonymous functions also (as in your $.getJSON example) } Test.prototype.change = function(event){ // currentField must be set from e.target // because this is `Test` instance console.log(this instanceof Test); // true console.log(event.target == $('input')[0]); // true this.currentField = event.target; // set new field }; function createTest(){ return new Test(); } $(function(){ // ready callback calls test factory var t1 = createTest(); }); 
+2
source

In most cases, I simply declare a local variable that references this, where I need a reference to this in the callback:

 function Foo() { } Foo.prototype.bar = function() { var that=this; setTimeout(function() { that.something="This goes to the right object"; }, 5000); } 

Alternatively, you can use bind () as follows:

 Function Foo() { this.bar = this.bar.bind(this); // ... repeated for each function ... } Foo.prototype.bar = function() { } 

This gives you that every time you create a new Foo instance, the methods are bound to the current instance, so you can use them as callback functions for setTimeout (), etc.

0
source

Source: https://habr.com/ru/post/1343842/


All Articles