Renaming built in javascript functions - javascript

Can one rename a built in JavaScript function?
I am trying to rename the "reverse" function to another name,
but still have it do the same function

You can change the name by creating an alias in the prototype for the function
Array.prototype.newreversename = Array.prototype.reverse;
var arr=["abc","sssd"];
console.log(arr.newreversename())
You can also create a wrapper function for the new function
Array.prototype.newreversefunction = function() {
return this.reverse();
};
var arr=["a","c"];
console.log(arr.newreversefunction())

You can, but don't
This is called monkey patching. Javascript is flexible enough to allow you to change fundamental things like this, but you will break other code and make your own code unreadable by others if you modify normal parts of the language this way.
That said, you can assign and clear things, even in prototypes like this
Array.prototype.rev = Array.prototype.reverse
> function reverse() { [native code] }
Array.prototype.reverse = null
> null
[1,2,3,4,5].rev()
> [5, 4, 3, 2, 1]
[1,2,3,4,5].reverse()
> "[1,2,3,4,5].reverse is not a function"

You can, but I would strongly recommend against doing so.
The proper way to do it would be to get the property descriptor for the method from the prototype (Object.getOwnPropertyDescriptor), then use that to define a new property (Object.defineProperty), and use delete to get rid of the previous one:
Object.defineProperty(
Array.prototype,
"thingy",
Object.getOwnPropertyDescriptor(Array.prototype, "reverse")
);
delete Array.prototype.reverse;
console.log([1,2,3].thingy()); // [3, 2, 1]
console.log([1,2,3].reverse()); // Error

You can do it like this:
Array.prototype.myReverse = Array.prototype.reverse;
delete Array.prototype.reverse;
But you should avoid this, as many libraries rely on the reverse function. Instead, if you want to call it using another name, just do the first line:
Array.prototype.myReverse = Array.prototype.reverse;

You can change the name by creating an alias
Array.prototype.slicing = Array.prototype.slice;
var animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slicing(2))

Related

Is there something wrong with using window['variableAsString']?

It's been very useful for writing functions that require iterating through variables, but I've heard users advising against using similar methods.
Is there something wrong with writing code this way?
Example of use:
Say I have three arrays and want to add a value to all three:
array1=[];
array2=[1,2];
array3=[4,4];
for (var i=1;i< 4; i++){
window['array'+i].push(1);
}
If you're going to need to iterate through a set of variables, plan ahead and put them inside an object:
var myArrays = {
array1: [],
array2: [1, 2],
array3: [4, 4],
"any-name-you-want-works": []
};
Accessing them is still straightforward:
myArrays.array1.push(1);
myArrays["any-name-you-want-works"].push(1);
Adding a new array to myArrays:
myArrays.array4 = [3, 5];
And iterating is made easy (this is the recommended way):
for (var arr in myArrays) {
if (object.hasOwnProperty(arr)) {
arr.push(1);
}
}
If you don't need to support old browsers, you can use newer features as well (source):
Object.keys(myArrays).forEach(function(key, index) {
myArrays[key].push(1);
});
More info on Object.keys().
Then, if you're using a popular lib like underscore or lodash, you can do lots of thing easily on objects and arrays:
_.chain(myArrays)
.each(function(arr) { arr.push(1) }) // adds one to each array
.first() // takes the first array
.map(function(val) { return val *2; }) // and multiply each value
.reverse() // then reverse those values
.value(); // and get the array
As I mentioned in a comment, you shouldn't pollute the global window object and also iterate through it to avoid collision or unexpected behaviors.
Wrapping your code inside an IIFE (Immediatly-Invoked Function Expression) is always a good idea, instead of using the global scope, for multiple reasons, but that's a whole other discussion and we can achieve what you want without it (for this question anyway).
It's not good practice to stick all of your variables in the global scope. There are certain cases where it's acceptable, for instance if you have a library that you want to be available everywhere, but it's generally best to avoid using window, particularly in the way you are using it. The good news is you don't need window to do what you want to at all. You can just add your arrays as attributes on an object, and reference them using strings the same way you did with window (which is just a globally scoped object). Note the use of var to scope the object locally.
var arrays = {
array1: [],
array2: [1,2],
array3: [4,4]
};
for (var i=1;i< 4; i++){
arrays['array'+i].push(1);
}

Accessing parameters when the function expects none Javascript

I am writing a Javascript function to count the number of instances of an element in an unsorted array. It has a method signature like this
Array.prototype.numberOfOccurrences = function() {
}
Here is an example of expected behavior
var arr = [4, 0, 4];
Test.assertEquals(arr.numberOfOccurrences(4), 2);
My problem is that I don't know how to access the elements in the array. The function doesn't take any parameters so how do I reference the array being passed in?
Note: The instructions aren't very descriptive for this kata on code wars and adding a parameter to the function returns some error unexpected token.
Inside the function you are creating into the Array.prototype you can access all the prototype functions through the "this" keyword.
Meaning you can access the array items using numeric properties like this[0] or this[1] to a access the first and second item respectively.
You can also call functions which allows you to iterate over each item on the array, such as: forEach, filter, etc.
Please refer this page to see everything you can do with the array prototype:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype
Lastly don't forget that the JavaScript implementation varies on each browser, so a function that works on Chrome, might not work on InternetExplorer, always confirm on caniuse.com If the function you are used has the same implementation on your targets browsers.
Cheers.
Whether you should extend javascript base objects aside, this is your friend:
Array.prototype.numberOfOccurrences = function(valueToFind) {
return this.filter(function(item) {
return item === valueToFind;
}).length;
}
var a = [1,2,3,3,3,3];
console.log(a.numberOfOccurrences(3)); //4
As noted above, if you're not able to change the function signature for whatever reason you can specify it as follows:
Array.prototype.numberOfOccurrences = function() {
var valueToFind = arguments[0];
...
}
I would recommend adding the parameter to the function for clarities sake. Seems counter intuitive for a function like numberOfOccurences to not take in a parameter - numberOfOccurences of what?
Fiddle: http://jsfiddle.net/KyleMuir/g82b3f98/
You might try using the locally available variable 'arguments' inside of the function. So for example, your code might look like thsi:
Array.prototype.numberOfOccurrences = function() {
var args = arguments || {};
var testArray, testCheck;
if (args[0] && Array.isArray(args[0]) {
// do something with the array that was the first argument, like:
testArray = args[0];
testCheck = testArray.indexOf(args[1]);
return testCheck;
} else {
// do what you want to do if the function doesn't receive any arguments or the first argument
// received isn't an array.
}
}
'arguments' is always available to you inside a declared function.

Please explain usage of _.identity(value) of underscore.js

Please explain usage of _.identity(value) of underscore.js. Not able to understand it from the documentation ( http://underscorejs.org/#identity ).
Can you provide some example of its usage?
A JavaScript code pattern involving identity is filtering values based on truthiness, e.g.
var a = [null, null, [1,2,3], null, [10, 12], null];
a.filter(_.identity)
yields [Array[3], Array[2]].
Using
_.compact(a)
is clearer, but one may not use lodash or underscore at all, e.g.
function identity(x) {
return x;
}
a.filter(identity)
Whether it is a good code pattern is questionable for several reasons, but it's being used in the wild.
It is not a NOOP at all. A NOOP is an imperative construct in e.g. assembly, whereas in functional programming, it is like other functions in that it returns a value. If identity were a NOOP, then all pure functions could also be considered noop, and it would not be a sensible thing.
It's essentially a no-operation function. It returns the value of whatever was passed into it.
The part about it being used as a "default iterator" within the library itself means that in other functions which may have an optional "iterator" parameter (which is likely used as a function to apply to each element of an array of some kind), if no iterator parameter is passed, the library will use this "no-op" iterator instead and the elements of the array will remain unchanged.
A specific example:
Underscore.js defines _.each and as like this.
_.each = function(obj, iterator, context) {
...
}
This iterator shows el value. You maybe have used this idiom.
_.each([1, 2, 3], function(el){
console.log(el);
});
This iterator returns el value without change.
_.each([1, 2, 3], function(el){
return el;
});
The function that returns a value without change occur frequently. So Underscore.js wants to define the function. Underscore.js names the function _.identity.
_.identity = function(value) {
return value;
};
If Underscore.js wants to use a default iterator, all Underscore.js need is call _.identity.
_.each([1, 2, 3], _.identity);

javascript create new method

using prototype method we can create new methods... like...
Object.prototype.newMethod=function(){
// do something
}
Here I am defining the newMethod with an anonymous function... now if I want to use this method, I have to use it like: <object>.newMethod();
But now I want to create a new method which I can use like: <object>.newMethod;... no brackets... How can I do that...??
please don't use any jQuery...
Erm, you can't. To call a method, you write parentheses after it. Otherwise you're just referencing it.
The only exception to this rule is when you write something like new Date, where the parentheses are implict due to the new keyword and only because there are no arguments given.
I can't really understand why you would want to do that, but it is possible, albeit with a nasty hacky workaround. What you're actually looking for, AFAIK, is a magic property (like the someArray.length property).
var foo = {val:'foo'};
foo.length = (function(that)
{
return function()
{
return that.val.length;
}
})(foo);
//at this point foo.length(); returns 3, but still requires parentheses
//so, build another closure, and assign a valueOf method to the lenth method:
foo.length.valueOf = (function(method)
{
return function()
{
return method();//call the length method
}
})(foo.length);
console.log(foo.length +1);//logs 4
foo.val += 'bar';
console.log(foo.length);//logs 6
//BUT:: be carefull!!
alert(foo.length);//coerces to string, we haven't redefined the toString method, so the function code will be alerted
alert(foo.length + '');//alerts 6
This is just to show you that, yes it is theoretically possible, but please, please, don't use this kind of overly polluted hacks... I haven't thoroughly tested this, but ATM, I've already noticed that console.log(foo.length); can return a different value, not sure why, yet:
foo = {val:'foo'};
foo.length = (function(that){return function(){ return that.val.length;};})(foo);
foo.length.valueOf = (function(method){return function(){return method();};})(foo.length);
foo.length;//returns 3, great
foo.val += 'bar';
console.log(foo.length);//logged 3 at first, now it's back to logging 6!<-- don't trust this is the conclusion
The only way to call a function without parenthesis would be to define it using getters and setters.
Note these are new to JavaScript 1.8 and are not supported by all browsers.

How to make short name to an Array property

I often have typos in typing word "length" and would like to make a short name to this property. For example "len"
I can easily make an Array method:
Array.prototype.len = function(){ return this.length }
but then i should call [1,2,3].len() with brackets...
But how to make a property? (and call it with [1,2,3].len )
I've tried something like this:
Array.prototype.len = (function(arr) {return arr.length})(this)
but this isn't seen in such way
Thanks in advance
Define a getter like this:
Array.prototype.__defineGetter__("len", function() {
return this.length;
});
var arr = [1, 2, 3];
arr.len // 3
(Please note: as mentioned in the comments above, it's usually a bad idea to modify the prototype of a native object. Also note that browser support for JavaScript getters/setters is probably sketchy.)

Categories

Resources