John Boe
John Boe

Reputation: 3611

Why I cannot access prototype function (using closures)?

I am trying to create function findStrings which should share it's variables with the function init, stringSplit and stringSearch.

String.prototype.findStrings = (function () {
  var action = 'split';
  var params = ',';
  var init = function (action = 'split', params = ',') 
  { this.stringSplit(); }
  var stringSplit = function (action) 
  { return this.init(); }
 var stringSearch = function (action) 
  {return this.init(); }
  return init;
})();

What I need. When I call test.findStrings('split'); it should 1) initiate variables by calling init 2) then call stringSplit so this should be string test.

When I call var result = test.findStrings( 'search', { params ... } ); 1) initiate variables, process arguments from object params 2) then call stringsSearch and this should be test.

var test = '#a > :matches(.b, #c)'; 
test.findStrings('split', "," );
var result = test.findStrings( 'search', { params ... } );

Error which I got is saying that this does not have stringSplit (because this is Window) and I need to this to be test.

How to access the test string within the functions and make it possible to access the variables and arguments within them?

Actually, I could remove the function searchStrings to simplify it.

Solution:

String.prototype.findStrings = (function () {
  var text = this;
...
String.prototype.init = function (action = 'split', params = ',') {
  text.stringSplit();
  }
}

There were two errors.

Upvotes: 0

Views: 78

Answers (2)

Matt Way
Matt Way

Reputation: 33161

I need to this to be test.

When init() is first called, this does equal test. The problem is that stringSplit and stringSearch are just variables, and have nothing to do with the current context.

Either way, the code is pretty difficult to understand. If you really want to override String, then why don't you do something like:

String.prototype.findStrings = function(action = 'split', params = ',') {
    // do logic here (not entirely sure what you want to accomplish)
    return (action === 'split') ? this.stringSplit() : this.stringSearch();
}

// Add other functions also to string prototype
String.prototype.stringSplit = function() { ... }
String.prototype.stringSearch = function() { ... }

Personally though, I don't like adding methods to types like String for various reasons. Why not adopt a more functional approach, and create functions that you simply pass strings to, and get an appropriate result?

For example:

function findStrings(str, params){
    // do logic and return result
}

Upvotes: 2

Sergiu
Sergiu

Reputation: 1396

First of all, you have a circular reference in your code: the init function calls stringSplit which calls init.

But to reach to that problem you should remove the this keyword from your prototype function. this will get the value of the object that is calling your function, in your case the window object, but your functions are created in a closure so you can't access them using the window object.

Upvotes: 0

Related Questions