I had a test interview and for 3 questions I didn't know the answer:
Write a function that will insert underscore between characters: this will become t_h_i_s.
Write a function that will output this:
l('t') === 'lt'
l()('t') === 'l3t'
l()()('t') === 'l33t'
l()()('g') === 'l33g'
l()()()()()()()()()()()('t') === 'l33333333333t'
Why the output is true?
var bar = true;
function foo() {
bar = false;
return 5;
function bar() {}
}
foo();
console.log(bar);
Can someone help please with the answers?
Write a function that will insert underscore between characters: this will become t_h_i_s.
You want to write a function that iterates over all characters in a string, and appends an underscore between all characters.
For example:
function underscoreString(str) {
var result = str.charAt(0);
for (var i=1; i<str.length; i++) {
result += '_' + str.charAt(i);
}
return result;
}
console.log( underscoreString('this') );
Write a function that will output this:
You will need to write a function that returns another function, so you can chain the functions. Since Javascript allows you to store functions as variables, you can make use of this by re-calling the same function continuously until a proper argument is returned.
The following function is an example. It works as intended but is not the most beautiful.
function l(ch) {
var str = 'l';
if (ch) return str + ch;
else str += '3';
var newFunc = function (ch) {
if (ch) return str + ch;
str += '3';
return newFunc;
}
return newFunc
}
console.log( l('t') === 'lt' );
console.log( l()('t') === 'l3t' );
console.log( l()()('t') === 'l33t' );
console.log( l()()('g') === 'l33g' );
console.log( l()()()()()()()()()()()('t') === 'l33333333333t' );
Why the output is true?
var bar = true;
function foo() {
bar = false;
return 5;
function bar() {}
}
foo();
console.log(bar);
The bar that is within the function foo() is not referencing the global variable bar. Instead, it is referencing the function function bar() {}. This is because of hoisting, as mentioned in the comments.
Thus, the global bar variable is not touched at all by the function, and stays true at all times.
It really depends on the expected level of code. If you need to demonstrate understanding of algorithms or knowledge of how to use javascript constructs.
For example, the first one could be as simple as:
function insertUnderscore(x){
return x.split('').join('_');
}
2nd question a recursive method:
function l( end ){
var acc = '';
function iter( eChar ){
if( typeof eChar === "undefined"){
acc=acc+'3';
return iter;
}
return 'l'+acc+eChar;
}
if(typeof end === "undefined"){
acc = acc + '3';
return iter;
}
return iter(end);
}
Third question:
function bar(){} actually declares 'bar' within the local scope, so your assignment bar = false acts on local 'bar'.
This one simply returns the iterator function if the letter is undefined, When the letter is defined it repeats the character '3' n times.
The other two should be pretty easy to figure out
function l(letter) {
let count = 0
function iter(letter) {
if (typeof letter === 'undefined') {
count++
return iter
} else {
return 'l' + ('3'.repeat(count)) + letter
}
}
return iter(letter)
}
console.log(l('t') === 'lt')
console.log(l()('t') === 'l3t')
console.log(l()()('t') === 'l33t')
console.log(l()()('g') === 'l33g')
console.log(l()()()()()()()()()()()('t') === 'l33333333333t')
Question 1
Use a negative lookahead for the beginning of the string and a positive lookahead for a character. Replace the given empty string with an underscore.
function spacer(s) {
return s.replace(/(?!^.)(?=.)/g, '_');
}
console.log(spacer('this'));
Question 2
Use a closure and return for a non given paramter the function otherwise the extended value.
function l(v) {
var s = 'l';
fn = function (v) {
s += 3;
return v === undefined ? fn : s + v;
};
return v === undefined ? fn : s + v;
}
console.log(l('t') === 'lt');
console.log(l()('t') === 'l3t');
console.log(l()()('t') === 'l33t');
console.log(l()()('g') === 'l33g');
console.log(l()()()()()()()()()()()('t') === 'l33333333333t');
Question 3
Because function bar() {} is hoisted to the begin of the function and then overwritten with false. The outer bar variable has never changed it's content.
var bar = true;
function foo() {
bar = false;
console.log('foo\'s bar:', bar);
return 5;
function bar() {}
}
foo();
console.log(bar);
Related
So I have this code:
<script>
function add7(n) {
let x = n + 7;
console.log(x);
}
function lastLetter(theString) {
let x = lastIndexOf(theString);
console.log(x);
})
</script>
<script>
function multiply(a, b) {
let ans = a * b;
console.log(ans);
}
</script>
<script>
function capitalize(word) {
if (word = String) {
toLowerCase(word);
charAt(0).toUpperCase(word);
console.log(word);
} else {
console.log("not a string");
}
}
</script>
I write functionName(chosenVariable) in the console and expected to see a clear answer but add7 and lastLetter just returns ReferenceError (function) not defined. and the other 2 get undefined as an answer. I know that I am blind but am I also a bit stupid? I've looked at the code and tried different changes but cant get it to work.
There were a few errors with your code
Extra ) at the end of the first script block
lastIndexOf is not defined anywhere on your script
word = String will just assign the value of the String class to the word variable (and always return true)
Strings are immutable, so you can't edit an existing string you can however create a new string based on another, so using word.toLowerCase() on it's own won't do anything, you need to reassign the value
add7(2);
lastLetter("123123");
multiply(2, 3);
capitalize("asd");
function add7(n) {
let x = n + 7;
console.log(x);
}
function lastLetter(theString) {
let x = theString[theString.length - 1];
console.log(x);
}
function multiply(a, b) {
let ans = a * b;
console.log(ans);
}
function capitalize(word) {
if (typeof word === "string") {
word = word.toLowerCase();
word = word[0].toUpperCase() + word.substring(1);
console.log(word);
} else {
console.log("not a string");
}
}
How would you write a function that is like this
f()()
f('it') == fit
f()('x') == fox
I have
function f(s){
return "f"+s;
}
I had to discern what you're looking for not only from your question, but also from your comments. It looks like every string begins with 'f', and each empty bracket-pair appends an 'o'. Finally, a non-empty bracket-pair appends its argument.
I actually think this is a cool metaprogramming challenge.
This should work:
let f = (str, depth=0) => str
? `f${'o'.repeat(depth)}${str}` // If given param, terminate
: str => f(str, depth + 1); // If no param, return func
// "fit"
console.log(f('it'));
// "fox"
console.log(f()('x'));
// "fortress"
console.log(f()('rtress'));
// "football"
console.log(f()()('tball'));
// "foooooool!!!"
console.log(f()()()()()()()('l!!!'));
You have only 3 required outputs and no additional behavior requirements explained. Hence, the simplest approach would be:
let f = arg =>
arg ? 'f' + arg : arg => arg ? 'fo' + arg : '';
console.log(f()()); // ''
console.log(f('it')); // 'fit'
console.log(f()('x')); // 'fox'
You could return a function for more than one call of the function and implement a toString method to get the final string.
function f(v) {
var s = 'f' + (v || 'o');
function g(v) {
s += v || 'o';
return g;
};
g.toString = function () { return s; };
return g;
}
console.log(f()()); // foo
console.log(f('it')); // fit
console.log(f()('x')); // fox
console.log(f()()('b')('a')('r')); // foobar
That's a very strange function to want, but you can do it by having your named function return an anonymous function if you didn't get a parameter the first time:
function f(s, str) {
if(typeof str === "undefined") {
str = "f"
}
if(typeof s === "undefined") {
return function(t) {
return f(t, str + "o")
}
} else {
return str + s;
}
}
Haha I saw this problem the other day, I used function currying:
var f = s => s ? `f${s}` : (g=o=>e=>e?`f${o+e}`:g(o+'o')) && g('o')
console.log(f('x'))
console.log(f()()('l'))
console.log(f()()()('bar'))
I think I'm using the wrong terminology but here is what I would like to do. Using a function like this one:
function isNumeric(){
if (isNaN(this)) { return false; }
var x = parseFloat(this);
return (x | 0) === x;
};
I know this function won't work as is. I removed the parameter that was originally passed in and replaced it inside the function with this. I would like to call it like so:
var tmp1 = 10;
var tmp2 = "10";
if( tmp1.isNumeric() == true && tmp2.isNumeric() == true ){
...
}
Instead of this:
if( isNumeric(tmp1) == true && isNumeric(tmp2) == true ){
...
}
The way to achieve that is not considered a good option, but it's to modify the prototype chain for the types of data you want your function to work with, e.g. for number and string like your example you could have:
Number.prototype.isNumeric = String.prototype.isNumeric = function() {
// ...
}
What you have currently is the preferred option because it won't contaminate the prototype chain for inbuilt types, risk conflicts with other libraries, potentially overwrite functionality you didn't know existed, etc. You could meet halfway with something like:
class Val {
constructor(value) {
this.value = value;
}
isNumeric() {
if (isNaN(this.value)) { return false; }
var x = parseFloat(this.value);
return (x | 0) === x;
}
}
Used like:
var tmp1 = new Val(10);
var tmp2 = new Val('10');
console.log(tmp1.isNumeric(), tmp1.isNumeric());
try to add this function to Object.prototype
Object.prototype.isNumeric = function () {
return parseFloat(this) == this;
};
Below may be a better option for the class function if you are wanting "10" to return that is it not a number.
isNumeric() {
return typeof this.value === 'number';
}
isNumeric is just a function - what you are looking for is an object method. Right now, tmp1 and tmp2 are a Number, and String respectively, and neither of those have a function called isNumeric. You can restructure those variables like this if you want:
function TmpValue (initValue) {
this.value = initValue
}
TmpValue.prototype.isNumeric = function() {
if (isNaN(this.value)) { return false; }
var x = parseFloat(this.value);
return (x | 0) === x;
}
var tmp1 = new TmpValue(10);
var tmp2 = new TmpValue('10');
For example, say I have a function defined as follows:
function foo() {
return "Hello, serialized world!";
}
I want to be able to serialize that function and store it using localStorage. How can I go about doing that?
Most browsers (Chrome, Safari, Firefox, possibly others) return the definition of functions from the .toString() method:
> function foo() { return 42; }
> foo.toString()
"function foo() { return 42; }"
Just be careful because native functions won't serialize properly. For example:
> alert.toString()
"function alert() { [native code] }"
function foo() {
alert('native function');
return 'Hello, serialised world!';
}
Serializing
var storedFunction = foo.toString();
Deserializing
var actualFunction = new Function('return ' + foo.toString())()
Explanation
foo.toString() will be string version of the function foo
"function foo() { ... return 'Hello, serialised world!';}"
But new Function takes the body of a function and not the function itself.
See MDN: Function
So we can create a function that returns us back this function and assign it to some variable.
"return function foo() { ... return 'Hello, serialised world!';}"
So now when we pass this string to the constructor we get a function and we immediately execute it to get back our original function. :)
I made this answer to address some pretty big flaws with the existing answers: .toString()/eval() and new Function() on their own wont work at all if your function uses this or named arguments (function (named, arg) {}), respectively.
Using toJSON() below, all you need to do is call JSON.stringify() as usual on the function, and use Function.deserialise when parse()ing.
The following wont work for concise functions (hello => 'there'), but for standard ES5 fat functions it'll return it as it was defined, closures notwithstanding of course. My other answer will work with all that ES6 goodness.
Function.prototype.toJSON = function() {
var parts = this
.toString()
.match(/^\s*function[^(]*\(([^)]*)\)\s*{(.*)}\s*$/)
;
if (parts == null)
throw 'Function form not supported';
return [
'window.Function',
parts[1].trim().split(/\s*,\s*/),
parts[2]
];
};
Function.deserialise = function(key, data) {
return (data instanceof Array && data[0] == 'window.Function') ?
new (Function.bind.apply(Function, [Function].concat(data[1], [data[2]]))) :
data
;
};
Take a look at the DEMO
At it's simplest:
var test = function(where) { return 'hello ' + where; };
test = JSON.parse(JSON.stringify(test), Function.deserialise);
console.log(test('there'));
//prints 'hello there'
More usefully, you can serialise entire objects containing functions and pull them back out:
test = {
a : 2,
run : function(x, y, z) { return this.a + x + y + z; }
};
var serialised = JSON.stringify(test);
console.log(serialised);
console.log(typeof serialised);
var tester = JSON.parse(serialised, Function.deserialise);
console.log(tester.run(3, 4, 5));
Outputs:
{"a":2,"run":["window.Function",["x","y","z"]," return this.a + x + y + z; "]}
string
14
I didn't test older IE's, but it works on IE11, FF, Chrome, Edge.
NB, the name of the function is lost, if you use that property then there's nothing you can do, really.
You can change it to not use prototype easily, but that's for you to do if that's what you need.
If you needed a way to serialise Arrow Functions in ES6 I have written a serialiser that makes everything work.
All you need to do is call JSON.stringify() as usual on the function or object containing the function, and call Function.deserialise on the other side for the magic to work.
Obviously you shouldn't expect closures to work, it is serialisation after all, but defaults, destructuring, this, arguments, class member functions, it'll all be preserved.
If you're only using ES5 notations please just use my other answer. This one really is above and beyond
Here's the demonstration
Working in Chrome/Firefox/Edge.
Bellow is the output from the demo; a few functions, the serialised string, then calling the new function created after deserialisation.
test = {
//make the function
run : function name(x, y, z) { return this.a + x + y + z; },
a : 2
};
//serialise it, see what it looks like
test = JSON.stringify(test) //{"run":["window.Function",["x","y","z"],"return this.a + x + y + z;"],"a":2}
test = JSON.parse(test, Function.deserialise)
//see if `this` worked, should be 2+3+4+5 : 14
test.run(3, 4, 5) //14
test = () => 7
test = JSON.stringify(test) //["window.Function",[""],"return 7"]
JSON.parse(test, Function.deserialise)() //7
test = material => material.length
test = JSON.stringify(test) //["window.Function",["material"],"return material.length"]
JSON.parse(test, Function.deserialise)([1, 2, 3]) //3
test = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c
test = JSON.stringify(test) //["window.Function",["[a, b] = [1, 2]","{ x: c } = { x: a + b }"],"return a + b + c"]
JSON.parse(test, Function.deserialise)([3, 4]) //14
class Bob {
constructor(bob) { this.bob = bob; }
//a fat function with no `function` keyword!!
test() { return this.bob; }
toJSON() { return {bob:this.bob, test:this.test} }
}
test = new Bob(7);
test.test(); //7
test = JSON.stringify(test); //{"bob":7,"test":["window.Function",[""],"return this.bob;"]}
test = JSON.parse(test, Function.deserialise);
test.test(); //7
And finally, the magic
Function.deserialise = function(key, data) {
return (data instanceof Array && data[0] == 'window.Function') ?
new (Function.bind.apply(Function, [Function].concat(data[1], [data[2]]))) :
data
;
};
Function.prototype.toJSON = function() {
var whitespace = /\s/;
var pair = /\(\)|\[\]|\{\}/;
var args = new Array();
var string = this.toString();
var fat = (new RegExp(
'^\s*(' +
((this.name) ? this.name + '|' : '') +
'function' +
')[^)]*\\('
)).test(string);
var state = 'start';
var depth = new Array();
var tmp;
for (var index = 0; index < string.length; ++index) {
var ch = string[index];
switch (state) {
case 'start':
if (whitespace.test(ch) || (fat && ch != '('))
continue;
if (ch == '(') {
state = 'arg';
tmp = index + 1;
}
else {
state = 'singleArg';
tmp = index;
}
break;
case 'arg':
case 'singleArg':
var escaped = depth.length > 0 && depth[depth.length - 1] == '\\';
if (escaped) {
depth.pop();
continue;
}
if (whitespace.test(ch))
continue;
switch (ch) {
case '\\':
depth.push(ch);
break;
case ']':
case '}':
case ')':
if (depth.length > 0) {
if (pair.test(depth[depth.length - 1] + ch))
depth.pop();
continue;
}
if (state == 'singleArg')
throw '';
args.push(string.substring(tmp, index).trim());
state = (fat) ? 'body' : 'arrow';
break;
case ',':
if (depth.length > 0)
continue;
if (state == 'singleArg')
throw '';
args.push(string.substring(tmp, index).trim());
tmp = index + 1;
break;
case '>':
if (depth.length > 0)
continue;
if (string[index - 1] != '=')
continue;
if (state == 'arg')
throw '';
args.push(string.substring(tmp, index - 1).trim());
state = 'body';
break;
case '{':
case '[':
case '(':
if (
depth.length < 1 ||
!(depth[depth.length - 1] == '"' || depth[depth.length - 1] == '\'')
)
depth.push(ch);
break;
case '"':
if (depth.length < 1)
depth.push(ch);
else if (depth[depth.length - 1] == '"')
depth.pop();
break;
case '\'':
if (depth.length < 1)
depth.push(ch);
else if (depth[depth.length - 1] == '\'')
depth.pop();
break;
}
break;
case 'arrow':
if (whitespace.test(ch))
continue;
if (ch != '=')
throw '';
if (string[++index] != '>')
throw '';
state = 'body';
break;
case 'body':
if (whitespace.test(ch))
continue;
string = string.substring(index);
if (ch == '{')
string = string.replace(/^{\s*(.*)\s*}\s*$/, '$1');
else
string = 'return ' + string.trim();
index = string.length;
break;
default:
throw '';
}
}
return ['window.Function', args, string];
};
Don't serialize the call, instead try serializing the info, allowing to repeat the call, which can include things like class & method names, arguments passed into the call or just a call scenario name.
w = (function(x){
return function(y){
return x+y;
};
});""+w returns "function(x){
return function(y){
return x+y;
};
}" but ""+w(3) returns "function(y){
return x+y;
}"
which is not the same as w(3) which somehow still remembers to add 3.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How do I make a default value for a parameter to a javascript function
in PHP:
function func($a = 10, $b = 20){
// if func() is called with no arguments $a will be 10 and $ b will be 20
}
How can you do this in JavaScript?
I get a error if I try to assign values in function arguments
missing ) after formal parameters
In javascript you can call a function (even if it has parameters) without parameters.
So you can add default values like this:
function func(a, b){
if (typeof(a)==='undefined') a = 10;
if (typeof(b)==='undefined') b = 20;
//your code
}
and then you can call it like func(); to use default parameters.
Here's a test:
function func(a, b){
if (typeof(a)==='undefined') a = 10;
if (typeof(b)==='undefined') b = 20;
alert("A: "+a+"\nB: "+b);
}
//testing
func();
func(80);
func(100,200);
ES2015 onwards:
From ES6/ES2015, we have default parameters in the language specification. So we can just do something simple like,
function A(a, b = 4, c = 5) {
}
or combined with ES2015 destructuring,
function B({c} = {c: 2}, [d, e] = [3, 4]) {
}
For detailed explanation,
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/default_parameters
Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed.
Pre ES2015:
If you're going to handle values which are NOT Numbers, Strings, Boolean, NaN, or null you can simply use
(So, for Objects, Arrays and Functions that you plan never to send null, you can use)
param || DEFAULT_VALUE
for example,
function X(a) {
a = a || function() {};
}
Though this looks simple and kinda works, this is restrictive and can be an anti-pattern because || operates on all falsy values ("", null, NaN, false, 0) too - which makes this method impossible to assign a param the falsy value passed as the argument.
So, in order to handle only undefined values explicitly, the preferred approach would be,
function C(a, b) {
a = typeof a === 'undefined' ? DEFAULT_VALUE_A : a;
b = typeof b === 'undefined' ? DEFAULT_VALUE_B : b;
}
You have to check if the argument is undefined:
function func(a, b) {
if (a === undefined) a = "default value";
if (b === undefined) b = "default value";
}
Also note that this question has been answered before.
I have never seen it done that way in JavaScript. If you want a function with optional parameters that get assigned default values if the parameters are omitted, here's a way to do it:
function(a, b) {
if (typeof a == "undefined") {
a = 10;
}
if (typeof b == "undefined") {
a = 20;
}
alert("a: " + a + " b: " + b);
}
function func(a, b)
{
if (typeof a == 'undefined')
a = 10;
if (typeof b == 'undefined')
b = 20;
// do what you want ... for example
alert(a + ',' + b);
}
in shorthand
function func(a, b)
{
a = (typeof a == 'undefined')?10:a;
b = (typeof b == 'undefined')?20:b;
// do what you want ... for example
alert(a + ',' + b);
}
You cannot add default values for function parameters. But you can do this:
function tester(paramA, paramB){
if (typeof paramA == "undefined"){
paramA = defaultValue;
}
if (typeof paramB == "undefined"){
paramB = defaultValue;
}
}