Add Prototype Method on all Variables - javascript

Is it possible to add a Method to all Javascript Prototypes (Object,array,function,string,number,boolean)?
Just for Example.
If i would like to add a new Prototype getter, which returns the Type of the Variable, the create Timestamp or something else, how could I do that?
For Information: It's not about what this function does!
Edit:
I would like to access the Function like every other Prototypen Function:
myVariable.myMethod(myParam)

Every JavaScript variable is either an object, or it auto-boxes to an object (like string, boolean and number), or it is null or undefined explicitly.
So, it seems like if you want to add a method to all those, you can add a function to Object.prototype which they all extend like Bar suggested.
Object.prototype.myMagic = function(){
console.log("Hello");
};
"thisString".myMagic();
15.13.myMagic();
([]).myMagic();
Note that you are in fact not adding a function to the prototype of a string since a string is a primitive value and doesn't have a prototype, rather, you're adding a method to the prototype of Object - and strings "box" to String instances (which are objects) that extend Object and will have this method.
Also note that on ES5 systems, it's possible to create objects that do not extend Object.prototype via Object.create(null), in ES6 it's also possible to modify the prototype of objects via setPrototypeOf or __proto__. However, outside those edge cases it should work.

You can add it to Object.prototype. All other prototype instances extend Object.prototype, and will inherit it from there.
Object.prototype.myMethod=function() {
// ... whatever
};
Please note that extending built-in prototypes is not a recommended practice for "real-world" code.

Related

Using setters in Javascript to "override" properties

The MDN page about set seems to state that an
[ECMAScript 2015] setter must not appear in an object literal ... with a
data entry for the same property.
However when using the super keyword this no longer seems to apply.
class Foo {
constructor(bar){
this.bar = bar
}
set bar(newBar){
if (!newBar.match(/\w+/))
throw Error("Invalid bar value")
// I can use super despite not being a derived class.
return super.bar = newBar
}
}
const baz = new Foo("Baz")
baz.bar = "new value" // No recursion
This seems like a useful feature as the property doesn't have to be "hidden" by prefixing it with an underscore. Plus I don't have to mess with the property enumerability to avoid the "hidden" version from showing in a loop or serialization.
But the set syntax is a bit of a black-box and I can't tell what it's actually doing.
Am I breaking something here or is it okay to use?
Also what is super referencing here?
This seems like a useful feature as the property doesn't have to be "hidden" by prefixing it with an underscore or something. Plus I don't have to mess with the property enumerability to avoid the "hidden" version from showing in a loop or serialization.
No, it's not useful. It's a hack at best, and doesn't do what you expect.
There is nothing hidden here at all. You are creating a new property with the name bar on the instance itself, shadowing any getters/setters you had defined on the prototype. The second assignment does not get your setter caller. Also the instance property is a normal enumerable property, so it will show up in for in loops and serialisation.
Also what is "super" referencing here?
The super keyword refers to the prototype of the object that the method (or setter) is defined on, i.e. Object.getPrototypeOf(Foo.prototype). This is the Object.prototype in your case, since your class Foo doesn't extend anything.
The .foo access will be looked up on that prototype, and would normally find a method that you inherited from your parent class or something. When using that, the property reference super.foo will however make the receiver of the operation (i.e. what would the this keyword in a method invocation) be the current this instance, not the prototype.
In your case, it's not a method call but an assignment. This could run a setter inherited from the parent class, but in your case there is no Object.prototype.foo property so it will fall back to standard assignment on the target - and that target is the baz instance itself, where a new own property will be created.
So no, it is not okay to use.

why typeof(Function.prototype) is function

I am aware of the fact that Prototypes are object literal. So methods and properties can be defined on them. Function.prototype has some method like apply, call, bind, toString etc. So I thought a function's prototype should be a object literal. But I ran following code and encountered that Function.prototype is of type function !
console.log(typeof(Function.prototype)); // function
How come it is not a object literal itself ?
From the specification:
The Function prototype object is the intrinsic object %FunctionPrototype%. The Function prototype object is itself a built-in function object. When invoked, it accepts any arguments and returns undefined. It does not have a [[Construct]] internal method so it is not a constructor.
NOTE
The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.
(my emphasis)
If we go to the ES5 spec, it says:
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
...without offering any explanation for why that would be the case. That language is essentially unchanged in ES1, ES2, ES3, and ES5. I think the original idea was basically that that was what gave it its function-ness, although typeof (even in ES1) didn't look at the internal [[Class]], it looked at whether the thing implemented [[Call]] (as it still does). When something goes back all the way to ES1, one frequently has to just invoke the "because Eich did the first JavaScript in 10 days and yeah, weird stuff happens when you do that" argument. :-)
Side note: By "object literal" I take it you mean "plain object." (An "object literal" — what the specifiation calls an object initializer — is just a way to write an object in source code. There are other ways to create plain objects.)
An object literal is some JavaScript syntax for creating objects. It isn't a data type.
Functions are just a specific type of object in JavaScript. Anywhere you can have an object, you can have a function.
Let's say you have declared an array,
let arr = [ 1 , 2 ];
So, internally it will be created as
let arr = new Array ( 1, 2 );
This is the function constructor.
Have you ever thought about how the array got all functions like concate, map, filter, reduce etc.?
Internally when we create an instance from a function constructor, the prototype property of a function will be set to the prototype property of that newly created instance. Hense, this concate, map, filter, reduce get automatically associated with that function constructor. So that's how we can use that array properties by arr.map, arr.concate.
Actually the prototype property of a function is visible but the prototype property of an instance which is created by a function constructor is hidden. If you want to check then you can check it by obj_name.proto. It's a pointer towards that prototype property.
Now, you can see that the array "arr" is not the array internally. It's an instance of a function constructor. That's why if you check the type of the array, you will get the answer as object and also if you check the typeof(Array), you will get the answer as Function.
If you find it useful then please like it on
https://www.linkedin.com/posts/sh-jay_javascript-array-prototype-activity-6951547190049677312-Dqbn?utm_source=linkedin_share&utm_medium=member_desktop_web
Well, I don't think you mean object literal, as alluded to by other answers and comments.
alert(Function.prototype instanceof Object) // true
alert(Function.prototype instanceof Function) // true
alert(typeof Function.prototype) // function
It is an object. It's also a function. Also, all functions are objects. They're all following the rules just fine.
alert((function(){}) instanceof Object) // true
alert((function(){}) instanceof Function) // true
alert(typeof (function(){})) // function
One big happy we-all-derive-from-Object family. Why should the prototype of Function not be a function?
Now if you wanna get weird... let's get weird.
var notAFn = Object.create(Function.prototype);
alert(notAFn instanceof Function); // true
alert(typeof notAFn); // object
And no, you can't call notAFn(). Not until they add a call Symbol for that. :)
Oh hey, feel free to tell me why this isn't a good answer. I'll try to improve it.

Use cases of Object.create(null)?

If you create a regular javascript object using say var obj = {}; it will have the object prototype. Same goes for objects created using var obj = new MyClass(); Before Object.create was introduced there was no way around this. However nowadays it's possible to create an object with no prototype (respectively null as its prototype) using var obj = Object.create(null);.
Why is this important? What advantages does it bring? Are there any real world use cases?
It's a completely empty object (nothing inherited from any .prototype including Object.prototype), so you can be guaranteed that any property lookup will only succeed if the property was explicitly added to the object.
For example, if you want to store some data where you won't know the keys in advance, there's a possibility that a provided key will have the same name as a member of Object.prototype, and cause a bug.
In those cases, you need to do an explicit .hasOwnProperty() check to rule out unexpected inherited values. But if there's nothing inherited, your testing can be simplified to a if (key in my_object) { test, or perhaps a simple truthy test if (my_object[key]) { if appropriate.
Also, with no prototype chain, I would imagine that lookups of properties that turn out to not exist would be faster, since only the immediate object would need to be checked. Whether or not this pans out in reality (due to optimizations) would be determined with performance testing.
The only difference here between creating an object with {} and Object.create(null) is that the Object prototype will not be inherited from.
This means that any of the methods we typically assume we can call on any object will not exist, such as toString and valueOf. A list of these can be found here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
From a performance perspective, creating an object simply by {} is actually much faster, so unless you specifically cannot have the functions under the Object prototype you should not create objects in that manner.
http://jsperf.com/null-vs-empty-object-performance

Is there a super prototype "Object" of all objects in javascript? What is that Object(first letter in capital) in javascript

Is there a super prototype "Object" of all objects in javascript? What is that Object(first letter in capital) in javascript. In javascript Object is the prototype of all objects like Object class is super class of all classes in Java.
I think you mean, if you place something in Object.prototype will it be accessible by everything because they all extend Object. The simple answer, yes.
If you place something in Object.prototype then when you create an instance of say, XMLHttpRequest, then you will be able to access what you set. Like this:
Object.prototype.foo = 'bar';
var req = new XMLHttpRequest();
console.log(req.foo); // bar
Yes, Object is the topmost object in prototype hierarchy. However, it's not recommended to pollute Object.prototype because such properties would show in, for example, for-in loop (if you don't make them not enumerable). Also note that in IE up to version 8, host objects don't inherit from Object: document.body instanceof Object === false.
Just type Object.prototype in your console. You will see something like
To test the hypothesis that all functions in javascript extend from Object, just like all classes extend from Object in Java, see the following:
So the answer is yes.
But keep in mind that javascript uses prototypal inheritance, while in javascript all objects get the methods of Object on their prototype, just like in Java, other similarities will not hold.

Every Object is a function and every function is Object - Which is Correct?

I was reading this link JavaScript_syntax
This seems to be cyclic - that every function is an Object and every Object itself is a function. Which is the atomic one? Can someone explain in a better way?
Anything that is not a primitive type (undefined, null, number, string, boolean) is an object (or an instance) in JavaScript. That means function inherits from object.
Object instances can contain more instances which can be functions. That's what we call a "method" (since it has an automatic this variable).
Since you can't "call" every Object instance, not every object is a function.
I think this concept is often misunderstood.
A utility to visualize JS types relationship http://jstype.herokuapp.com/#/home
Javascript Data Types
Primitive types - numbers, strings, booleans, null and undefined.
All non-primitive types are object:
var foo = { };
var foo = [1, 2, 3];
var foo = function abc() { return "hello world"; };
var foo = new Number(30);
var foo = new String("Hello World");
var foo = new Boolean(true);
var foo = new RegExp(/[foo]+/);
// All 'foo` are object.
All primitive types have a corresponding Constructor Function wiz. Array, Number, String, Boolean, RegExp. As all functions are objects, they are objects too. So we can call them Constructor Function Objects.
Most of the non-primitive type has prototype property where all inherited stuff lives. Math doesn't have prototype.
All objects inherit from Object.prototype which inherits from null.
object <- Object.prototype <- null
All native functions inherit from Function.prototype which inherits from Object.prototype.
function <- Function.prototype <- Object.prototype <- null
Arrays inherit from Array.prototype which inherits from Object.prototype.
array <- Array.prototype <- Object.prototype <- null
Must read MDN: Inheritance and prototype chain
To get confused Stackoverflow: prototype in JavaScript
Stack Overflow: Function prototype explained
Every function is an object. Objects can contain functions (methods) but an object is not necessary a function.
Also Function is always a property of an object.
This mean that all functions in JavaScript is always bound to an object. If you don't specify an object to bind a function to it's bound to the window object (Also called global functions)
..fredrik
It would be better to say that in JavaScript everything can be treated as an object, that includes primitive types as well as functions types; what the JavaScript interpreter does is that it automatically promotes your primitives and functions to their object wrapper types when you interact with them.
There is also a Function object, an a number of equivalent Wrappers for the other primitives in JavaScript, that means that you can even call methods on functions instances, like:
myFunction(someArg).call(this)
That being said, not every object is in fact a function.
As others have said, functions are objects that can be passed around by reference like other javascript objects. Not all objects are functions, only those that are declared as such.
You will often see methods declared like so:
var myFunc = function(foo, bar) {
...
};
This is to reinforce the fact that the method is a function object and as such it is a property of the object where it is defined, just like any other variable you might define with var.
This is the foundation of the most important feature in javascript, closure.
Every function is an Object.
I'm not an javascript expert, but I cannot see how every Object is a function. (I can see how every object could be a function, but that's different)
Quoting from Working with Objects - MDN Docs
section Using Object Initializers last paragraph:
"In JavaScript 1.1 and earlier, you cannot use object initializers. You can create objects only using their constructor functions or using a function supplied by some other object for that purpose. See Using a Constructor Function."
meant that all objects WERE functions! Specifically, upon evaluation, instances or instantiations of functions.
Literally, ALL objects of that vintage were created syntactically with constructs like:
"newobj = new constructFunctor(arg1,arg2){this.prop1=arg1 /* etc */}(val1,val2)"
AND in the string that makes the object "newobj" there is the word "constructFunctor", the name of a function. The statement is intentionally quoted to impress the fact that it must be eval()'d to be executed. Prior to execution "newobj" is "equated to" a function because the statement MUST have one and "is" one by virtue of "constructFunctor"'s literal existence to define newobj's value upon execution. The quoting, and not, is very intentional in order to elucidate this abstraction. However, because JavaScript DOES have an eval function, this abstraction is in fact intentionally incorporated into the JavaScript language.
The legacy of this is still fundamental to JavaScript, though some syntactic short cuts have been added as "object initializers" using the shorthand notation like: "no={}". That the paragraph quoted above is still resident in the current documentation IS significant for the very reasons noted.
Furthermore, JavaScript also exemplifies the fundamental paradigms of Functional Programming. This defines everything as a function using the abstractions of Recursive Function Theory and the Lambda Calculus! For instance 0(), 1(), 2(), ... are the constant nonary functions better known as 0,1,2,3, ...
JavaScript is completely consistent with a Functional Programming Style approach rather than the common OOPS (pun intended Object Oriented Programming Style).
Just for supplementary to Aaron Digulla's answer.
In javascript not every object is a function. But Object,Array,String and many other built-in objects are functions that used with new operator to create object. I think this is what confused most people.
javascript everything is a hashtable. Ryan Dahl said this in one of his talks. thats what json is also; a hashtable definition. thats why u can access an object using array notation or object property notation. the value of the hashtable can be a function as well which is a hashtable. or rather an associative array
type Object in the console u get { [native code] } which is a hashtable
Object is an abstract data given to a class and that class is assigned to an object. Object can have properties and properties can hold values and functions.
Or simply for the sake of making it easy to understand you can say that anything that is not primitive data type (number,string, boolean, unll & undefined) can be classified as an object.
the selected answer by Aaron Digulla's is not 100% correct because it says,
Anything that is not a primitive type (undefined, null, number,
string, boolean) is an object.
but a string is an object. That is why you can do things like:
myString="Hello World";
x = myString.length;
newString = myString.toUpperCase();
link = myString.link("http://www.hello-world.com/");
And many other methods can be applied to the string object.
You could also initialize the string like:
myString = new String("Hello, World!");
But because a string is also a datatype it is much easier to initialize it by just applying a value.
Not necessarily an answer to the question ... just a clarification/correction of Aaron Digulla's answer.
The selected answer is wrong. In JavaScript everything is a function, except primitive types. Object itself is a function which is called function Object(). Use for example the following code:
<script>
alert(Object);
</script>

Categories

Resources