Searching for appropriate answer proved difficult because of the existence of many other problems related to my keywords, so I\'ll ask this here.
As we know, functio
If you just want to add custom properties to a function then you only need to add those properties to Function.prototype. For example:
Function.prototype.SomeNewProperty = function () {//Do something awesome here...}
Isnt it possible that after John Slegers:
Way 2 : adding properties after defining the function
Adding a Way 2.5
function doSomething() {
doSomething.prop = "Bundy";
doSomething.doSomethingElse = function() {
alert("Why Hello There! ;)");
};
let num = 3;
while(num > 0) {
alert(num);
num--;
}
}
sayHi();
sayHi.doSomethingElse();
alert(doSomething.prop);
var ref = doSomething;
ref();
ref.doSomethingElse();
alert(ref.prop);
Putting in both a "variable" property and a function property for completeness sake, straight in the function declaration. Thus avoiding it to be "disconnected". Left the inner default workings of the function (a simple loop) to show that it still works. No?
I agree that this is a difficult question that could have multiple answers, so I prefer to make an different example:
Let's suppose to have an JavaScript Array
, populated by a generator:
var arr = [...new Array(10).keys()];
that is
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Now we want to map this to a new array - same length, applying some function, so we could use the native map
function property:
arr = arr.map((value,index) => ++value)
We have just done a value=value+1
and return, so now the array will look like
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Ok, now supposed to have a JavaScript Object
like
var obj=new Object()
that was defined like the previous array (for some crazy reason):
arr.forEach((value,index) => obj[value]=value)
i.e.
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
At this point we cannot apply the same map
method since it's not defined for an Object
so we have to define it as a new prototype
of an Object
:
Object.defineProperty(Object.prototype, 'mapObject', {
value: function(f, ctx) {
ctx = ctx || this;
var self = this, result = {};
Object.keys(self).forEach(function(k) {
result[k] = f.call(ctx, self[k], k, self);
});
return result;
}
});
At this point we could do as for the array before:
obj=obj.mapObject((value,key) => ++value )
so that we have:
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}
You can see that we have updated the values only:
[...Object.keys(obj)]
["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
and we can turn back then into the output array:
[...Object.keys(obj).map(k=>obj[k])]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Here it is at work:
// Array.map
var arr = [...new Array(10).keys()];
console.log("array", arr)
arr = arr.map((value, index) => ++value)
console.log("mapped array", arr)
// new property
Object.defineProperty(Object.prototype, 'mapObject', {
value: function(f, ctx) {
ctx = ctx || this;
var self = this,
result = {};
Object.keys(self).forEach(function(k) {
result[k] = f.call(ctx, self[k], k, self);
});
return result;
}
});
// Object.mapObject
var obj = new Object()
arr = [...new Array(10).keys()];
arr.forEach((value, index) => obj[value] = value)
console.log("object", obj)
obj = obj.mapObject((value, key) => ++value)
console.log("mapped object", obj)
console.log("object keys", [...Object.keys(obj)])
console.log("object values", [...Object.keys(obj).map(k => obj[k])])
test = (function() {
var a = function() {
console.log("test is ok");
};
a.prop = "property is ok";
a.method = function(x, y) {
return x + y;
}
return a
})()
test();
console.log(test.prop);
console.log(test.method(3, 4));
Alternatively you have to use getters and setters
var person = {
firstName: 'Jimmy',
lastName: 'Smith',
get fullName() {
return this.firstName + ' ' + this.lastName;
},
set fullName(name) {
var words = name.toString().split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
}
console.log(person.firstName);
console.log(person.lastName);
console.log(person.fullName);
person.fullName = "Tom Jones";
console.log(person.fullName);