Have a look at the last two answers.
How can we determine without looking into any documentation that sliderinput.value is the right answer, and not sliderinput.value()?
Im coming from Java. Im used to call accessor methods.
What is "value" as opposed to "value()"?
What is sliderinput if not an object?
You can determine this by checking if value is a function:
typeof sliderinput.value === "function"
Javascript usually doesn't use getter functions like value(). If you want to use getters you can use the get syntax to create a getter function that can be called using normal property syntax. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
In the context of this quiz you've posted, I suppose they just want you to know from the top of your head that value is a property in this case.
How can we determine without looking into any documentation that sliderinput.value is the right answer, and not sliderinput.value()?
You can try it and see.
You can test its type (with the typeof operator) to see if it is a function or something else.
… but reading the documentation, despite you dismissing it, is the correct approach.
Note that the attribute value of sliderinput is a string, so the options with parenthesis () are not valid and will throw an error. You could do that only if value were a function type variable, which is not.
Edit: as other members pointed out, you can use typeof to check the variable type; in this case it will be "string"
Related
I'm updating a script that checks parameters like this:
if (config.param) {//do...}
This has lead to some issues in truthiness. I'd implemented a truthy() function as a prototype so as to be able to do the following:
if (config.param.truthy()) {//do...}
That seemed fine until I remembered that the config object only contains params being explicitly set. So config.value is usually undefined as opposed to false.
I'd added the prototype within an appropriate scope via String/Number/Boolean.prototype.truthy.
Is it possible to implement the prototype on the config object such that it will be able to return false on non-defined parameters?
Edit: My question is not about the truthiness (I can simply use a function), but instead how to implement a prototype on an object such that it is inherited by its properties, which may be different types or non-existent.
if ("param" in config && !!config.param) {//...
Or if you want to use a default value if undefined then
config.param = config.param || defaultValue
The whole problem with prototyping in this case is that falsey values will not get autoboxed to objects and so attempting to call methods of them will result in error.
Assuming that your params will all be different types of data, then your approach of adding prototype methods for Strings/Booleans/etc could work well. Then you could simply see if that property exists by doing
if (config.hasOwnProperty("param") && config.param.truthy() ) {//do...}
or if you're using dynamic property names
if( config.hasOwnProperty(param) && config[param].truthy() ) {//do...}
This doesn't work:
var s = '^foo';
console.log(['boot', 'foot'].some(s.match));
Uncaught TypeError: String.prototype.match called on null or undefined
But this does:
var s = '^foo';
console.log(['boot', 'foot'].some(function(i) { return i.match(s) }));
Why is this? I imagine somehow the String.prototype.match function is too "primitive" or something, but why exactly? Since I'm not using ES2015, the second version seems quite verbose. Is there an alternative?
EDIT
When I wrote the above, I actually got it backwards compared to my actual need, which was matching one string against a number of regexes. But thanks to the great answers and comments below, I get it: [/^foo/, /^boo/].some(''.match, 'boot').
Note: The value of this is determined by how the function is called! (exception: bound and arrow functions)
If you pass s.match to .some, then the function will be called with this set to the global object (e.g. window) not the string it "belongs" to.
I.e. it would be equivalent to this:
String.prototype.match.call(window, 'foo')
This cannot work because this has to refer to a string object.
You could solve this by binding the function to a specific this value:
['boot', 'foot'].some(s.match.bind(s));
Learn more about this:
MDN - this
You Don't Know JS: this or That?
How to access the correct `this` context inside a callback?
A function value in Javascript does not bring its object along with it. The value of s.match is a plain function value, with no knowledge that you happened to find it attached to s. In fact, no matter what String you access it through, it's always the same function value:
"foo".match === "bar".match
//= true
When you call a function through an object, Javascript sets this to that object for the duration of the function call. But as soon as anything comes between retrieving the function value and calling it, any object association is lost.
You can create a function that does remember a specific this value using bind, as in #Felix King's answer. someFunction.bind(someObject) has approximately the same meaning as function(arg1, arg2,...) { return someObject.someFunction(arg1, arg2,...); }, but it automatically handles the number of parameters properly.
I'm working on some existing code that looks something like this:
return this.getMyObject() && this.getMyObject().myArray[0];
As far as I can tell it is checking that the object returned by getMyObject() exists before returning the first item in it's myArray property. How does this work and is it good form?
Update: The reason for my question came from the confusion over how the && operator can be used to return a property value and not a boolean result. After further thought, to make it more readable I refactored the line to:
return this.getMyObject() ? this.getMyObject().myArray[0] : undefined;
Obviously I am assuming here that the myArray property will exist.
That code works because of type coercion. Some people will tell you its good and some people will say always truly check something using typeof
if (typeof someVariable === 'undefined')
Even in examples below the above check isn't enough. I don't know what is better but that code as far as I am concerned isn't how I write it myself but it is accepted with a lot of javascript developers. There are times that code in the correct conditions can still pass the first check and yet throw an error accessing the property. Depends how controlled your situation is that determines, to me, if you should or shouldn't allow it.
Example of passing first check and failing:
var myObject = 1;
var test = myObject && myObject.myArray[0];
Or as #JamesThorpe pointed out in comment above:
var myObject = {};
var test = myObject && myObject.myArray[0];
Also people familiar with some coding languages but not JS might look at that code and not understand what it means where checking with an if and then returning the value might be a bit more readable to others, which is also a plus I think.
It's correct form. If there is no object returned by this.getMyObject() then function will return false in another case second part of condition will be executed and returned as a result of function. It's good practice to check if object exists before calling any method on it, because an error could occur if not to do so.
But you should check an existence of an object only if you are not sure whether it exists.
I recently had an issue with some javascript that goes against every bone of my programming background. Javascript does this often to me, so I'm not that surprised.
I have a function as such...
function x(param1, booleanParam, arrayParam){
....
}
I was getting a runtime error saying that arrayParam.length was not defined. On debugging I saw this was true and went to find out why. Turns out I had forgotten a comma in my function call as such...
x(param1, true [arrayJunk]);
The problem I'm having is figuring out why this call was made at all? Why isn't this a compile error, how does Javascript see this and think, "Yeah, that seems like it might work!"
Thanks in advance for any enlightenment you can share!
That's an indexing expression.
It's the same syntax as someArray[someIndex].
It will end up passing undefined as the second parameter too, unless arrayJunk happens to be the name of a property of boolean primitives.
What happens is the following:
JavaScript engine converts true into a Boolean object (not the primitive)
It then tries to access the property name stored in arrayParam from that object
Property doesn't exist, so it returns undefined
If arrayParam was the string "toString", it would return a function object
In this case the expression was being interpreted as an index. Essentially the same as
someArray[42]
So it was being seen as a function call with 2 parameters instead of 3
Many dynamic languages don't check if you pass too many or too few arguments to a function.
While this can sometimes mask errors, it also allows you to roll your own defalut parameter scheme.
is there a way to check the type of an object in javascript against a custom type? I probably worded that wrong so let me show you what i'm wanting to do:
if(typeof value == "MyClassType")
console.log(true);
can you do this with typeof, instanceof, or anything like that? I'm wanting to throw an error if the user provides a value that's not a class i'm expecting.
Use the instanceof operator:
if (!(value instanceof MyClassType)) {
throw new Error("expected object of type 'MyClassType'");
}
Documentation: msdn, mdn
In javascript, you shouldn't really care if an object is a particular type. What you should care about is whether is has the methods that you expect. In fact, it should be OK to provide any object as long as that object has the appropriate methods on it that implement the expected behavior for those methods. That's one of the beauties of javascript. It isn't hard types and doesn't need to be. Heck look at the jQuery model. They make a jQuery object support the methods of an array so it can be used in place of an array in most situations even though it's not technically just an array.
So, I'd suggest that you should test the object to see if you see a few of the expected and needed methods on it and if you find them, then merrily proceed. If you don't find the methods you need, then throw an error. This will catch the general misuse issues right away while not overconstraining how a client might use the API.
You can test for the existence of a method/property with nothing more than this:
if (obj.makeQuackSound && obj.flySouthForWinter) {
// must be a duck
}
If you want to check if they were actually functions, not just properties, you could do that too.