Getting the "private method" in the "public function" class using CoffeeScript

I am doing a series of tests with classes and CoffeeScript / JavaScript. See the following code:

class Example someFunction = -> alert @getText() constructor: -> @text = 'Hello world! ;)' someFunction() getText: -> @text ### Instance ### example = new Example 

This is just an example, when compiling I get an error:

 Uncaught TypeError: Object [object global] has no method 'getText' 

Do you know how I can solve this problem? http://jsfiddle.net/P4Xdz/

+4
source share
4 answers

If you really want to do this, you need to manually specify @ (AKA this ) manually using call or apply :

 constructor: -> @text = 'Hello world! ;)' someFunction.call(@) 

Demo: http://jsfiddle.net/ambiguous/6KZrs/

The problem is that someFunction not any method, it is just a simple function. If you need it to behave like a method, you need to "methodize" it manually by specifying the desired @ when you call it. This (and epidemian ) offers an alternative approach: explicitly pass the object as an argument:

 someFunction = (ex) -> console.log ex.getText() constructor: -> @text = 'Hello world! ;)' someFunction(@) 

Demo: http://jsfiddle.net/ambiguous/hccDr/

Keep in mind that JavaScript is not public or private, therefore CoffeeScript is not public or private. You can pick up a fake, but fakery has holes and, as a rule, requires more pickyness (for example, manually supplying @ with call ) to make it work. If you look at the version of your JavaScript code, you will see that someFunction is only:

 var someFunction = function() { ... }; 

Just a function in a variable that is bound to a class function, nothing more. Also keep in mind that since someFunction is local to a function of the Example class, it will in no way be displayed in subclasses.

+6
source

This may be obvious, but ... coffescript cannot do anything conceptually, which you could no longer do in javascript. Currently, the definition of someFunction is a local variable and is not declared as an instance property (unlike getText).

When you use the "@" inside someFunction, I assume that you expect it to refer to an instance of the example, which would be convenient in your case, however someFunction is not defined in the example.

If you used obvalue =>, it still would not bind it to the instance (this applies to the class function). Now this may seem like an uncomfortable or odd choice of design, but its actually consistent. Once again, someFunction is not in the instance; it is defined as a local variable in the function of the Example class.

If you use β†’, '@' refers to javascripts 'this' for this function (which is a local variable and obviously does not contain getText). If you use =>, this refers to javascripts 'this' during the definition, which is currently a function of the Example class. The Example instance that you want to refer to has not yet been created (although you want to reference it).

Reason @ refers to an example instance inside functions such as getText, because javascripts this keyword refers to the object on which you defined. Coffeescript is actually no different, and the other provides you with convenient syntax for referencing 'this' when defining functions.

TL; DR:

You cannot accomplish what you are looking for, and you may have to abandon the idea of ​​the 'private' function on the instance. The best thing I see what you do is what you already described in your comments above Example.prototype.getText() Since the two ways you can access this method are an instance and Example.prototype (which is defined by a function). Since your method is not defined on the instance, you cannot use 'this'. However, if you call the method from the prototype, your getText function will fail.

 getText: -> @text 

@text refers to what getText defines, and in this context its prototype (and not the instance). And the text is undefined on the prototype.

If you want this method to function as you expect, you probably have to do it not 'private'. Javascript / Coffeescript do not have access modifiers such as public and private, a private method is really a function defined in a specific area. In this case, this area does not have access to what you want, and this keyword does not apply to what you need.

+3
source
  • You use someFunction = , not someFunction: This will not do what you expect.
  • You call someFunction when in fact you probably want to call @someFunction .
+1
source

As you wrote your example, "someFunction" is an anonymous function that is not tied to anything. So, β€œsomeFunction 'this' is bound to a global object, which explains your mistake. You can fix this by using the bold arrows to define" someFunction "and placing" someFunction "in the Example constructor. This will cause someFunction to be bound to to your example instance.If you bound "someFunction" with a thick arrow, but left it outside the constructor, as you originally would, "someFunction" would be bound to the Example constructor, resulting in "someFunction" calling the nonexistent static method --getText - Example .

Here's how to get rid of your error:

 class Example constructor: -> someFunction = => alert @getText() @text = 'Hello world! ;)' someFunction() getText: => @text ### Instance ### example = new Example 
-one
source

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


All Articles