Am not sure if functions in javascript are what we call methods in other programming languages.Methods in other programming languages can have their result specified just after the access-specifier like in C# for example i would do like
//method to return int
private int myinteger(){
int a=0;
return a;
}
//method to return string
private string mystring(){
string b="myreturn";
return b;
}
I just don't know how to do that with javascript functions, you think you can help me with a sample?Thank You very much :)
You don't need to provide the data types in javascript. The functions are pretty similar you just have to start it with the function keyword.
Also, we need to start the variables with const or let.
I use the console.log(myinteger()); below to log the value of the myinteger() function in the browser console. (Similar to c++'s cout)
//method to return int
function myinteger() {
const a = 0;
return a;
}
//method to return string
function mystring() {
const b = "myreturn";
return b;
}
console.log(myinteger());
console.log(mystring());
If you are someone who wants to use javascript but still want to assign the data type and many more thing then you can use TypeScript By Microsoft.
You cannot do this with javascript, but you still have two workarounds available:
Use eslint and use the https://eslint.org/docs/rules/consistent-return rule
Use typescript
Javascript has types for values (not variables)
so you can define a variable as
var name = "Hamond";
and to know it's type you have to use typeof
typeof name; // "string"
Side note: you can use let or const instead of var but let that be for another time.
so variables in javascript doesn't have types, values have.
You can add static typing using typescript so
var name: string = "Hamond";
and at dev time if you wanted to edit name and incorrectly deal with it as a non string type you will get an error
warning you immediately
name = 3; // error
name - 4; // error
// and so forth because `name` is of `string` type
so this type check is done at author or dev time and you don't have to wait until run time to get the error.
Why all the talk about variables and values?
Because Javascript function can return any value(even returning a variable is basically returning its value if it's scalar value or its reference if it's an object type)
so defining a function look like:
function doSomething(){
return 33;
}
notes:
no return type
can have no return statement(by default will return undefined)
with typescript
function doSomething(): number{
return 33;
}
typing problems solved at dev/write time
About function vs method:
I think developers in many times use these terms interchangeably, but in javascript we just have function, even a function defined inside a class in javascript is just a function. People like the name method when its defined inside some class.
references:
JS syntax
The Nature Of Functions
Related
I am reading a code written in Typescript. I'm not sure if I understand it correctly:
export class MyClass<B> {
value: B;
constructor(value: B) {
this.value = value;
}
isMyClass(): this is MyClass<B> {
return true;
}
}
What does the <B> stand for? What does it represent, a Type? If so, what Type is it?
What is this is MyClass<B> in isMyClass(): this is MyClass<B>? Is it being evaluated for true or false? Why not to put this inside of the function itself then, something like this:
isMyClass() {
if (this is MyClass) {
return true;
}
else {
return false;
}
}
And I am not able to find the answer to a these questions.
What does the <B> stand for? What does it represent, a Type? If so, what Type is it?
That's a type parameter, also known as generics. See the TS handbook.
In languages like C# and Java, one of the main tools in the toolbox for creating reusable components is generics, that is, being able to create a component that can work over a variety of types rather than a single one. This allows users to consume these components and use their own types.
Whenever one calls a function or creates an instance, if the function or class is generic, you can "pass" a type parameter to it, similar to how arguments can be passed to a function or constructor. (The difference is that the type parameter, being a type, doesn't exist in the emitted JS - it's just there to help TS type-check).
If so, what Type is it?
It's whatever type the constructor parameter is called with.
const m = new MyClass(3);
will result in
constructor(value: B)
where value is 3, telling TypeScript that the resulting instance is a MyClass<number> - in other words, that its value property holds a number, a B.
What is this is MyClass<B> in isMyClass(): this is MyClass<B>? Is it being evaluated for true or false? Why not to put this inside of the function itself then, something like this:
The
isMyClass(): this is MyClass<B> {
is a type guard. If the method returns true, it tells TypeScript that the instance is of type MyClass<B>.
While you could do something like:
isMyClass() {
if (this instanceof MyClass) {
return true;
}
else {
return false;
}
}
That wouldn't allow TypeScript to understand that the type has been narrowed when isMyClass is called; it'll just return a boolean. In contrast, using the is will both return a Boolean and give TypeScript type information about what was called.
I have a function that returns a variable, I'd just like to know what's the correct syntax for doing something (such as doing math or writing a new variable using that returned variable.
Example Function:
function exampleFunction(number) {
var data_filter = number + number;
return data_filter;
}
The function returns data_filter, and I'd like to know what's the correct syntax for doing something with it, such as inputting it in another function.
What you have here is fine.
As one of the comment suggests typically you assign the result to a variable. Take a simple example here:
let myNumber = 10;
let myHalvedNumber = halveNumber(myNumber);
console.log(myNumber)
console.log(myHalvedNumber);
function halveNumber(numberToHalve){
return numberToHalve/2;
}
The best way to think about it in practice is to treat the function/input combination { f(x) } as a proxy for the result itself. This means that both of these examples are correct and how you choose to employ it is your own preference.
//These two approaches are identical and both valid:
//1) Assign to a variable for further use - typically better for variable re-use:
let myHalvedNumber = halveNumber(10);
aSecondFunction(myHalvedNumber);
//2) Use the result directly in a second call - typically shorter and arguably easier to maintain/read
aSecondFunction(halveNumber(10));
function halveNumber(myNumber){
return myNumber/2;
}
function aSecondFunction (myNumber){
console.log("the number is: " + myNumber)
}
I come from a Java background, where everything is Object Oriented. While Getting into a bit more of Javascript (more into the class areas of javascript), I've noticed complete changes. The biggest for me is getting used to the prototyping of the so-called "classes" javascript has. So, my question is if you need to intialize the varialbes you pass into your class function constructor method-thing. For example:
function Foo(a, b, c) {
this.a = a;
var b = b;
this.c = "";
this.d = a + b;
}
Now In javascript is this necessary? Cause in Java, you have to show that the variable type definition in the argument itself: Foo(int a, int b, string c) Now how does the method in Javascript know what type of data structure it is being passed too? Like what if they passed in an array for a, and then my code tried to add the integer and the array together? That won't push the int too the array will it?
Sorry for being a bit questiony, I've been looking for an answer for a while on the Google... And it's getting late here.
Thanks for any help
Uneveris
So, my question is if you need to intialize the varialbes you pass into your class function constructor method-thing.
Do they need initializing, no. Javascript is a loosely typed language and declared variables can be of any type.
You do not need to declare a variable type for the arguments, they can be anything. Also note the vars are private variables in the scope of the constructor.
Now how does the method in Javascript know what type of data structure it is being passed too?
As a result of loose types, javascript has a type typeof to help work out what a variables type actually is if strong typing is required.
if (typeof this.a !== 'function')
throw "Expected a function, received a " + typeof this.a;
Verbose, but it fulfils its purpose.
typeof reference
Like what if they passed in an array for a, and then my code tried to add the integer and the array together? That won't push the int too the array will it?
Have you tried to do this?
var a = new Array();
var b = 1;
var c = a + b;
console.log(typeof c);
>> string
In Node.js the output is a string with the array values concatenated and the integer appended as a string on the end.
It is important when expecting a specific data structure that data you have been passed is what you are expecting. In JS, this is by conditionally checking.
If you are writing these classes purely for your self, duck typing can be useful. If it looks like a duck, quacks like a duck then it is a duck. This is to do with semantics when working in a loosely typed language like JS. Two assumptions === true.
What is duck typing
Hope this helps answer your questions.
You can't be sure what parameter types are being passed to your method. That is a main Javascript language trait which can be used for both good and bad.
So, what happens if there are wrong parameter types? Javascript will try to silently convert them to something common.
For example:
var a = [100,2,3];
var b = 5;
var c = a + b;
Adding an array and an integer (as well as string) will result in a string "100,2,35". Note that array is first converted to String, then 5 is simply appended to the end. This behaviour closely resembles the Java's one, that calls a toString() method of any object whenever it needs to concatenate.
You can avoid the wrong types in two ways. First, convert them yourself. Like,
a = Number.parseInt(a, 10); // now a is of type number
Second, if your method is important and highly dependent on the data correctness, you should not convert the params but avoid using them at all if they are of wrong type:
if (typeof a != "number") throw "Param must be int";
Finally, you can see this JS framework that supports strict typing:
http://betterjs.org/
In Ruby I think you can call a method that hasn't been defined and yet capture the name of the method called and do processing of this method at runtime.
Can Javascript do the same kind of thing ?
method_missing does not fit well with JavaScript for the same reason it does not exist in Python: in both languages, methods are just attributes that happen to be functions; and objects often have public attributes that are not callable. Contrast with Ruby, where the public interface of an object is 100% methods.
What is needed in JavaScript is a hook to catch access to missing attributes, whether they are methods or not. Python has it: see the __getattr__ special method.
The __noSuchMethod__ proposal by Mozilla introduced yet another inconsistency in a language riddled with them.
The way forward for JavaScript is the Proxy mechanism (also in ECMAscript Harmony), which is closer to the Python protocol for customizing attribute access than to Ruby's method_missing.
The ruby feature that you are explaining is called "method_missing" http://rubylearning.com/satishtalim/ruby_method_missing.htm.
It's a brand new feature that is present only in some browsers like Firefox (in the spider monkey Javascript engine). In SpiderMonkey it's called "__noSuchMethod__" https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/NoSuchMethod
Please read this article from Yehuda Katz http://yehudakatz.com/2008/08/18/method_missing-in-javascript/ for more details about the upcoming implementation.
Not at the moment, no. There is a proposal for ECMAScript Harmony, called proxies, which implements a similar (actually, much more powerful) feature, but ECMAScript Harmony isn't out yet and probably won't be for a couple of years.
You can use the Proxy class.
var myObj = {
someAttr: 'foo'
};
var p = new Proxy(myObj, {
get: function (target, methodOrAttributeName) {
// target is the first argument passed into new Proxy, aka. target is myObj
// First give the target a chance to handle it
if (Object.keys(target).indexOf(methodOrAttributeName) !== -1) {
return target[methodOrAttributeName];
}
// If the target did not have the method/attribute return whatever we want
// Explicitly handle certain cases
if (methodOrAttributeName === 'specialPants') {
return 'trousers';
}
// return our generic method_missing function
return function () {
// Use the special "arguments" object to access a variable number arguments
return 'For show, myObj.someAttr="' + target.someAttr + '" and "'
+ methodOrAttributeName + '" called with: ['
+ Array.prototype.slice.call(arguments).join(',') + ']';
}
}
});
console.log(p.specialPants);
// outputs: trousers
console.log(p.unknownMethod('hi', 'bye', 'ok'));
// outputs:
// For show, myObj.someAttr="foo" and "unknownMethod" called with: [hi,bye,ok]
About
You would use p in place of myObj.
You should be careful with get because it intercepts all attribute requests of p. So, p.specialPants() would result in an error because specialPants returns a string and not a function.
What's really going on with unknownMethod is equivalent to the following:
var unk = p.unkownMethod;
unk('hi', 'bye', 'ok');
This works because functions are objects in javascript.
Bonus
If you know the number of arguments you expect, you can declare them as normal in the returned function.
eg:
...
get: function (target, name) {
return function(expectedArg1, expectedArg2) {
...
I've created a library for javascript that let you use method_missing in javascript: https://github.com/ramadis/unmiss
It uses ES6 Proxies to work. Here is an example using ES6 Class inheritance. However you can also use decorators to achieve the same results.
import { MethodMissingClass } from 'unmiss'
class Example extends MethodMissingClass {
methodMissing(name, ...args) {
console.log(`Method ${name} was called with arguments: ${args.join(' ')}`);
}
}
const instance = new Example;
instance.what('is', 'this');
> Method what was called with arguments: is this
No, there is no metaprogramming capability in javascript directly analogous to ruby's method_missing hook. The interpreter simply raises an Error which the calling code can catch but cannot be detected by the object being accessed. There are some answers here about defining functions at run time, but that's not the same thing. You can do lots of metaprogramming, changing specific instances of objects, defining functions, doing functional things like memoizing and decorators. But there's no dynamic metaprogramming of missing functions as there is in ruby or python.
I came to this question because I was looking for a way to fall through to another object if the method wasn't present on the first object. It's not quite as flexible as what your asking - for instance if a method is missing from both then it will fail.
I was thinking of doing this for a little library I've got that helps configure extjs objects in a way that also makes them more testable. I had seperate calls to actually get hold of the objects for interaction and thought this might be a nice way of sticking those calls together by effectively returning an augmented type
I can think of two ways of doing this:
Prototypes
You can do this using prototypes - as stuff falls through to the prototype if it isn't on the actual object. It seems like this wouldn't work if the set of functions you want drop through to use the this keyword - obviously your object wont know or care about stuff that the other one knows about.
If its all your own code and you aren't using this and constructors ... which is a good idea for lots of reasons then you can do it like this:
var makeHorse = function () {
var neigh = "neigh";
return {
doTheNoise: function () {
return neigh + " is all im saying"
},
setNeigh: function (newNoise) {
neigh = newNoise;
}
}
};
var createSomething = function (fallThrough) {
var constructor = function () {};
constructor.prototype = fallThrough;
var instance = new constructor();
instance.someMethod = function () {
console.log("aaaaa");
};
instance.callTheOther = function () {
var theNoise = instance.doTheNoise();
console.log(theNoise);
};
return instance;
};
var firstHorse = makeHorse();
var secondHorse = makeHorse();
secondHorse.setNeigh("mooo");
var firstWrapper = createSomething(firstHorse);
var secondWrapper = createSomething(secondHorse);
var nothingWrapper = createSomething();
firstWrapper.someMethod();
firstWrapper.callTheOther();
console.log(firstWrapper.doTheNoise());
secondWrapper.someMethod();
secondWrapper.callTheOther();
console.log(secondWrapper.doTheNoise());
nothingWrapper.someMethod();
//this call fails as we dont have this method on the fall through object (which is undefined)
console.log(nothingWrapper.doTheNoise());
This doesn't work for my use case as the extjs guys have not only mistakenly used 'this' they've also built a whole crazy classical inheritance type system on the principal of using prototypes and 'this'.
This is actually the first time I've used prototypes/constructors and I was slightly baffled that you can't just set the prototype - you also have to use a constructor. There is a magic field in objects (at least in firefox) call __proto which is basically the real prototype. it seems the actual prototype field is only used at construction time... how confusing!
Copying methods
This method is probably more expensive but seems more elegant to me and will also work on code that is using this (eg so you can use it to wrap library objects). It will also work on stuff written using the functional/closure style aswell - I've just illustrated it with this/constructors to show it works with stuff like that.
Here's the mods:
//this is now a constructor
var MakeHorse = function () {
this.neigh = "neigh";
};
MakeHorse.prototype.doTheNoise = function () {
return this.neigh + " is all im saying"
};
MakeHorse.prototype.setNeigh = function (newNoise) {
this.neigh = newNoise;
};
var createSomething = function (fallThrough) {
var instance = {
someMethod : function () {
console.log("aaaaa");
},
callTheOther : function () {
//note this has had to change to directly call the fallThrough object
var theNoise = fallThrough.doTheNoise();
console.log(theNoise);
}
};
//copy stuff over but not if it already exists
for (var propertyName in fallThrough)
if (!instance.hasOwnProperty(propertyName))
instance[propertyName] = fallThrough[propertyName];
return instance;
};
var firstHorse = new MakeHorse();
var secondHorse = new MakeHorse();
secondHorse.setNeigh("mooo");
var firstWrapper = createSomething(firstHorse);
var secondWrapper = createSomething(secondHorse);
var nothingWrapper = createSomething();
firstWrapper.someMethod();
firstWrapper.callTheOther();
console.log(firstWrapper.doTheNoise());
secondWrapper.someMethod();
secondWrapper.callTheOther();
console.log(secondWrapper.doTheNoise());
nothingWrapper.someMethod();
//this call fails as we dont have this method on the fall through object (which is undefined)
console.log(nothingWrapper.doTheNoise());
I was actually anticipating having to use bind in there somewhere but it appears not to be necessary.
Not to my knowledge, but you can simulate it by initializing the function to null at first and then replacing the implementation later.
var foo = null;
var bar = function() { alert(foo()); } // Appear to use foo before definition
// ...
foo = function() { return "ABC"; } /* Define the function */
bar(); /* Alert box pops up with "ABC" */
This trick is similar to a C# trick for implementing recursive lambdas, as described here.
The only downside is that if you do use foo before it's defined, you'll get an error for trying to call null as though it were a function, rather than a more descriptive error message. But you would expect to get some error message for using a function before it's defined.
I have an AngularJS service coded in Typescript. I call the functions of the service with a parameter like this setFalse('retrieve'):
class StateService implements IStateService {
state = [];
get = (property: string) => {
return this.state[property];
}
setFalse = (property: string) => {
this.state[property] = false;
}
setNull = (property: string) => {
this.state[property] = null;
}
setTrue = (property: string) => {
this.state[property] = true;
}
// more code here
}
Is there some way that I could remove the need for the quoted string 'retrieve', use a constant or check the values being used before run time?
1. Is there some way that I could remove the need for the quoted string 'retrieve'?
You could desugar the overload, and provide lots of different versions of the function.
//just to give the idea
function setFalse_retrieve(){ return setFalse('retrieve') }
The upside of doing this is that its really typesafe and there is no way to ever call setFalse with a bad parameter. The downside is that there is lots of boilerplate and you can't pass around a property value if you want to.
2. Use a constant?
Typescript has an enum feature for this:
enum Properties { retrieve, frobnicate };
You can now use Properties.retrieve instead of "retrieve" in your code and it will catch any typos in the enum name.
Properties.retriev; // Error: The property 'retriev' does not exist on value of type 'typeof Properties'.
Just be aware that Typescript makes the enum values be integers so you will need to convert them to strings when calling the Angular functions:
var enumProperty = Properties.retrieve; // 0
var strProperty = Properties[enumProperty]; // "retrieve"
The downside of the enum approach is that you can pass any number where an enum value is expected and the error will not be detected at runtime (do don't do that):
var x:Property = 10; // :(
3. Use a constant or check the values being used before run time
Typescript has function overloading on function constants but AFAIK, you can only use it to specialize return types depending on inputs, not to restrict your valid inputs to a set of constants. That is, you would still need to have a generic case that accepts any string, which is not what you want.