How to trigger a anynomous function with parameters Javascript - javascript

Today I was at job interview - and I had been presented with a task.
I have never encoutered such a function, so there it is:
Write down a function which after triggering like this:
console.log('hello'.repeatify(3))
returns
hellohellohello
I was trying to create an empty object and append a method repeatify, however i just don't know how to trigger it just with 'hello'.
Maybe i should change console.log method?
Thanks for the help :)

Wasn't that really hard. You have to make a new function for String.prototype and use repeat() function to multiply given string by given argument.
String.prototype.repeatify = function(count){
return this.repeat(count);
};
console.log('hello'.repeatify(3))

You can create your own prototype methods for every object, but you shouldn't do it with native objects:
String.prototype.repeatify = function(num) {
return this.repeat(num);
}
console.log('hello'.repeatify(3));
read more about this bad practice here

String.prototype.repeatify = function(amount)
{
var endString = "";
for(var i = 0; i < amount; ++i)
{
endString += this;
}
return endString;
}

Just modify String's prototype object:
String.prototype.repeatify = function (A) {
var i = 1;
var a = this;
while (i++ < A) {
a += this;
}
return a;
}
console.log('hello'.repeatify(3));
// outputs hellohellohello
There are mixed feelings on modifying the prototype of built in objects. I have both that it is just fine and that it is a bad practice. Personally I try to avoid it and prefer defining a standalone function to modifying the prototype of something I didn't create.

ES6 version
repeatify
String.prototype.repeatify = String.prototype.repeatify || function (times = 1) {
// ES5 this
return [...``.padStart(times, ` `)].map((item, i) => item = this).join(``);
};
`abx`.repeatify(3);
// "abxabxabx"

Related

Create a Logger for an object in Javascript

I want to write a logger that takes one object argument (build-in or user-defined) and returns new object which acts as argument and has the same methods, and also each method call is logged in browser console.
For example:
var a = [];
var b = myLogger(a);
b.push("foo");
< array.push("foo") -> 1;
b.push("bar");
< array.push("bar") -> 2;
As far as I understand I need to create a decorator to solve this. Is this right way to solve this task? Any other suggestions are also appreciated.
function myLogger (target) {
var handler = {
get(target, name){
var result = name in target? target[name] : undefined;
console.log(`< ${JSON.stringify(target)}.${name} -> ${result}`);
return result;
}
};
return new Proxy(target, handler);
}
var a = { x: 1};
var a_Proxy = myLogger(a);
a_Proxy.x; // logs < {"x":1}.x -> 1
use can use ES6 "Proxy" standard built-in object.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Proxy

Attempt to create a each() type jQuery function using Javascript from scratch

My goal is to replicate the normal jQuery each type function from scratch using only Javascript. Here is my code so far:
// Created a jQuery like object reference
function $(object) {
return document.querySelectorAll(object);
this.each = function() {
for (var j = 0; j < object.length; j++) {
return object[j];
}
}
}
console.log($('.dd')); // returns NodeList[li.dd, li.dd]
$('.opened').each(function() {
console.log(this);
}); // Results in an error [TypeError: $(...).each is not a function]
As you can see, each is showing as a error. How should I go about fixing this?
A lightweight class that works like that would be:
function $(selector) {
// This function is a constructor, i.e. mean to be called like x = new $(...)
// We use the standard "forgot constructor" trick to provide the same
// results even if it's called without "new"
if (!(this instanceof $)) return new $(selector);
// Assign some public properties on the object
this.selector = selector;
this.nodes = document.querySelectorAll(selector);
}
// Provide an .each function on the object's prototype (helps a lot if you are
// going to be creating lots of these objects).
$.prototype.each = function(callback) {
for(var i = 0; i < this.nodes.length; ++i) {
callback.call(this.nodes[i], i);
}
return this; // to allow chaining like jQuery does
}
// You can also define any other helper methods you want on $.prototype
You can use it like this:
$("div").each(function(index) { console.log(this); });
The pattern I 've used here is widely known (in fact jQuery itself also uses it) and will serve you well in a great many cases.
something like this...??
function $(object) {
var obj = {
arr : document.querySelectorAll(object),
each : function(fun){
for (var i = 0; i < this.arr.length; i++) {
fun.call(this, this.arr[i]);
}
}
}
return obj;
}

Return a dynamically generated function without eval()

I'm trying to dynamically create function when iterating over an array and
I need the arguments in the array to be set according to the value of the current index.
For example:
var array = ['apple','orange','banana'];
I need to have these three functions:
function() { return 'apple' };
function() { return 'orange' };
function() { return 'banana' };
I tried to return a constructed function from an external one but the expression in it won't evaluate and I end up with three of these:
function() { return array[i] };
Is there a way to dynamically create such a function without using eval()?
You can create the functions like so:
var funcs = {};
for (var i=0;i<array.length;i++)
{
funcs[array[i]] = (function(val)
{
return function()
{
return val;
};
}(array[i]));
}
which can be called like so:
funcs.apple();// returns "apple"
But also, depending on the value of some var:
var someVar = 'banana';
if (funcs.hasOwnProperty(someVar))
{
funcs[someVar]();
}
If what you're after is a single (possibly global) function, that depending on, for example, the URI, you just have to write this:
var myFunc = (function()
{
var retVal = location.mathname.match(/^\/([^\/]+)/)[1];
return function()
{
return retVal;
};
}());
Note that the function won't be hoisted, as it is an expression.
I've written a lot about IIFE's (Immediatly Invoked Function Expressions), how they work and why, so best check my answer here if you don't fully understand these code snippets. It's quite easy once you get the logic, and you'll soon find yourself writing code like this all the time... tey really are incredibly powerful things, closures are!
This is what I would do:
function constant(value) {
return function () {
return value;
};
}
var array = ["apple", "orange", "banana"];
var fruit = array.map(constant);
alert(fruit[0]()); // apple
alert(fruit[1]()); // orange
alert(fruit[2]()); // banana
Simple. See the demo: http://jsfiddle.net/tfS2F/
You can also use the initial array as a key as follows:
alert(fruit[array.indexOf("orange")]()); // orange
See the demo: http://jsfiddle.net/tfS2F/1/
This one will not work, i leave it to illustrate the infamous loop problem:
The best way to achieve this would be to create a context var before creating the function, hope this illustrates it http://jsfiddle.net/jkymq/
var array = ['apple','orange','banana'];
var methods = {}
for (pos = 0 ; pos < array.length; pos ++){
var target = array[pos];
var newMethod = function(){alert (target);}
methods[target] = newMethod;
}
for (foo in methods){
methods[foo]();
}

Dynamically firing a named-spaced method via JavaScript

I have multiple external JavaScripts that are namespaced based on the section of the site. I am trying to dynamically fire methods, but am unable to get the methods to fire. Can anyone tell me what the problem is?
If I add this, the method fires:
Namespace.Something.init()
But when I try to do it like this, nothing happens (note: namespace equals Namespace.Something and functionname equals init):
namespace[functionname]();
Unless you want to use eval which I am sure you don't the following works.
This assumes that all your methods are the same level deep i.e namespace.somename.somemethod
var Namespace = {
Something: {
init: function() {
console.log('init called');
}
}
};
Namespace.Something.init();
var namespace = "Namespace";
var section = "Something";
var method = "init";
this[namespace][section][method]();
as Namespace is part of the global scope you can access it from this[namespace]
I asked the same question a few weeks ago, though I think I phrased it slightly differently. See this.
Basically, you need to parse the string functionname one piece at a time.
By the way, using the walk_path code from that answer, here's a general purpose function I wrote to run a function from a string including arguments.
// run an arbitrary function from a string. Will attempt to parse the args from parenthesis, if none found, will
// use additional arguments passed to this function.
utils.runFunction = function (funcdef) {
var argPos = funcdef.indexOf('(');
var endArgPos = -1;
var args = undefined;
var func = funcdef;
if (argPos > 0) {
endArgPos = funcdef.indexOf(')', argPos);
if (endArgPos > 0) {
args = funcdef.substring(argPos + 1, endArgPos).split(',');
func = funcdef.substring(0, argPos - 1);
}
} else {
args = Array.prototype.slice.call(arguments, 1);
}
var func = walk_path(window, func);
return !args ? func() : func.apply(null, args);
};
var methodName = 'Namespace.Something.init';
var methodParts = methodName.split('.');
var method = this;
for (var i=0; i < methodParts.length; i++) {
method = method[methodParts[i]];
};
method(the arguments you want);

Rewriting the JS String Constructor: Am I Way Off?

I'm on my way through Object Oriented Javascript, and I can't help but feel I've missed the boat on a given exercise. So what I'm looking for here is pointers on how I can improve my code or understanding of Constructors. Here was the challenge:
Imagine the String() constructor
didn't exist. Create a constructor
function MyString() that acts like
String() as closely as possible.
You're not allowed to use any built-in
string methods or properties, and
remember that String() doesn't exist.
You can use this code to test your
constructor:
--
var s = new MyString('hello');
s.length(); s[0]; s.toString();
s.valueOf(); s.charAt(1);
s.charAt('2'); s.charAt('e');
s.concat(' world!'); s.slice(1,3);
s.slice(0,-1); s.split('e);
s.split('l'); s.reverse();
And here was my response, which fails on one or two accounts, but I'm more interested in the actual structure of it. Am I completely off-base? Is there somewhere I can view the actual String constructor implemented by browsers to compare?
function MyString(string){
a = string.split("");
this.length = a.length;
this.toString = function(){
return a.join("");
};
this.valueOf = function(){
if(a.length > 0 && string !== 0 && string !== false && string !== undefined){
return true;
} else {
return false;
}
};
this.charAt = function(index){
return a[index];
};
this.concat = function(addition){
return string + addition;
};
this.slice = function(begin, end){
var a2 = new Array();
if(end < 0){
end = parseInt(a.length) + end;
}
for(y = begin;y<end;y++){
a2 += a[y];
}
return a2;
};
this.split = function(splitter){
spPos = parseInt(a.indexOf(splitter));
var split1 = a.slice(0,spPos);
var split2 = a.slice(spPos + 1, a.length);
var joined = new Array();
return joined.concat(split1.join(""), split2.join(""));
};
this.reverse = function(){
var ar = a.reverse();
return ar.join("");
};
return this;
}
I'm headed to bed, but I'll be up and responding in the morning. Thanks so much for any guidance you can give on this issue.
A quick point about the structure of your class, as mentioned before.
Your class is written in such a way so that all the methods are inside the constructor. So when you initialise a new class all the methods are regenerated. Thus if you have more than one instance of class MyString on the page this won't be the most efficient technique. You should consider using the prototyping technique instead. So your constructor would simply become:
function MyString(string){
a = string.split("");
this.length = a.length;
}
Your methods are then declared outside the constructor and as such are not regenerated each time a new instance of MyString is created.
MyString.prototype.toString = function(){ return a.join(""); }
MyString.prototype.charAt = function(index){ return a[index]; }
Firstly, browsers generally have the String implementation in some kind of native code. You won't be able to view that code.
Considering that you are keen on improving your code, is it ok for you not make 'a' private, or may be at least to have a function that returns a. This depends on your requirements basically. The reason I ask is that it is really important to note the number of functions created each time your constructor is called. To avoid this you should move these functions into the prototype of the MyString function, so that the functions are used by all instances of MyString. That way you won't be creating multiple instances of the same function. But again this depends on whether you are ok letting 'a' be accessible outside the function (but at the same time it makes a huge difference in the number of function objects created).
I think the answer marked as correct is not entirely right. If you do:
var hello = new MyString('hello');
var bye = new MyString('bye');
hello.toString() // returns "bye"
Maybe the solution to it could be:
function MyString(string){
this.a = string.split("");
this.length = this.a.length;
}
MyString.prototype.toString = function(){ return this.a.join(""); }
MyString.prototype.charAt = function(index){ return this.a[index]; }

Categories

Resources