Where are built-in method in javascript? - javascript

please help me get it straight, I see every object in javascript leads to object Object in prototype chain and then to null, in console.log we can see properties and methods of objects but never its implementation, i wonder if this Object is a top-level object where all built-in are stored, is that so?
thank you all for answers!

Javascript is an object-based language. Which means that "everything" inherits from an Object, except Object itself, the top of the prototype chain is null. When you declare an array, you can use .lenght because that is defined in the prototype attribute. There are some exceptions, such as int, floats, etc.
In fact, when you run a console, you can see every method from its parents. Try creating a Constructor for a new object, let's say, for example:
var Person = function(name, yearOfBirth, job) {
this.name = name;
this.yearOfBirth = yearOfBirth;
this.job = job;
}
Add a method to this Person's prototype:
Person.prototype.calculateAge = function() {
console.log(2016 - this.yearOfBirth);
};
And create an instance of this new "class":
var sarah = new Person('Sarah', 1994, 'programmer');
Now go to the console on your browser and type sarah to see it's methods and variables. You'll notice that variables that are exclusive for John will appear on the first drop-down, but you'll also notice that John does not have calculateAge attached directly to it. That's because it's in its prototype, search for something called _proto_ and you'll see this method and also a construct and guess what else? Another _proto_, this time, it's the proto from Person's parent, or, in other words, the Object.
There you can find most of the methods from the Object itself.
Prototypes are what makes inheritance possible in javascript

Perhaps you want to look at ECMA specifications?
http://www.ecma-international.org/publications/standards/Ecma-262.htm
Each browser may have its own implementation of Javascript. Maybe something like this repo will help.
https://github.com/v8/v8

Related

Understanding Prototypal inheritance (Javascript)

I'm trying to understand how prototypal inheritance works when using constructor functions in Javascript. Take the following code for example:
let Animal = function (name, species, birthYear) {
this.name = name;
this.species = species;
this.birthYear = birthYear;
};
let spike = new Animal(`Spike`, `Dog`, 2000);
Animal.prototype.calculateAge = function () {
let age = 2022 - this.birthYear;
return age;
};
Animal.prototype.color = `brown`;
spike.calculateAge();
console.log(spike.color);
console.log(spike);
These last three lines are what I'm struggling to understand. Please let me know if my understanding is misguided at any point in my explanation.
I can call the calculateAge() method on the spike object because it inherited the method from the Animal prototype. Similarly, I can log spikes color property to the console because the spike object inherited the color property from the Animal prototype. When I inspect the spike object using console.log(), it has the properties of name, species, and birthYear that I defined, but there is also a prototype. Does this mean that the spike object contains the prototype, or is this simply identifying the prototype from which it inherited the aforementioned method and property? Also, I don't really feel like I understand what this Animal prototype is. I get that the code works and that's all well and good, but just what in the world is this Animal prototype thing? Is it its own object in and of itself?
Thank you for any explanation you can offer.
I think you should first deeply understand the object oriented paradigm behind Javascript.
Javascript is a prototype based object oriented programming language.
The operations are encoded in the prototype data structure in a prototype language, which is copied and updated at run time.
However, a class is still the equivalence class for all objects with the same state space and methods when viewed abstractly.
You're effectively creating an element of a new equivalence class when you add a method to the prototype.
So, why are you doing that? Mostly because it results in a run-time system that is straightforward, logical, and elegant. To create a new object or class, simply do a deep copy, which copies all of the data as well as the prototype data structure. Then you get inheritance and polymorphism for almost nothing: A method lookup always entails requesting a method implementation by name from a dictionary.
To be more specific, JavaScript is a prototype-based object-oriented language, which means it doesn't have classes and instead defines behaviors using constructor functions, which can then be reused using the prototype.

A Way to move an instance to another class in javascript

I was actually practicing creating classes and instances of them using the new keyword and this came to my mind.
Suppose I have a superclass called Customers and I have two subclasses which are newCustomers and specialCustomers.
Suppose that I have a new customer called bob ==> var bob = new newCustomer();
and I have a special customer called smith ==>>
var smith = new specialCustomer();
How can I write a method that when assigned to bob, it moves him from being a newCustomer instance to a specialCustomer instance?
like for example, what code should I write to make this work:
bob.moveToSpecial() //moves bob from being instance of newCust to specialCust
An object is not an instance of a class, an object has a prototype based upon the constructor called.
What you can do (although it may lead to side-effects) is changing the prototype of that object:
bob.__proto__ = specialCust.prototype;
Read about the warnings when doing this here: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
A better way is to create a new object and move all properties from bob there:
newBob = new specialCust();
for(var prop in bob){
newBob[prop] = bob[prop];
}
Be aware that in both cases, bob loses his "inherited" methods and properties from the old prototype, although in the latter case only the non-enumerable ones (as stated in the comments). The enumerable ones will get copied and bound to the new object directly, possibly overriding inherited methods, so be aware of that, too.
Also worth reading: https://reinteractive.com/posts/235-es6-classes-and-javascript-prototypes
[edit] Example code with Object.keys:
newBob = new specialCust();
Object.keys(bob).forEach(function(prop){
newBob[prop] = bob[prop];
});

Javascript: Is there a scenario where one would prefer to declare an object property using prototype?

I've just started to learn Javascript.
As per my understanding so far, you can declare class/static variables in two ways. The 1st way:
Blog.prototype.signature = "By Blogger-Name";
And the 2nd way:
Blog.signature = "By Blogger-Name";
By using the first method, the variable signature is available to all instances of Blog.
However, a variable that remains the same value for all instances of a class should really not be an instance variable. As I see it, class/static variables should be declared using the second method only.
Hence, my question is, is there a scenario where one would be required/forced to declare variables the first way? Or is my understanding of all of this lacking in any way? Please let me know.
EDIT: In what instances is the first method preferred and, similarly, in what instances is the second method preferred?
EDIT 2: So I've learnt that the first method actually adds instance properties with a default value. This can also be achieved by setting a default value in the constructor itself. So when would adding a property this way (i.e. using prototype) be preferred?
Hence, my question is, is there a scenario where one would be required/forced to declare variables the first way?
The only thing that comes to mind would be if you needed to allow for code using an object created via new Blog to access the property without knowing the constructor function's name. E.g.:
function useABlogInstance(blog) {
// Here, assume I don't know that `blog` was created via `new Blog`
console.log(blog.signature);
}
Although a canny user could do
console.log(blog.constructor.signature);
to access Blog.signature (assuming you maintain the constructor backlink), that wouldn't be very clean. :-)
It's important to note that a property on Blog.prototype isn't a "class" or "static" property, it's an instance property (on the Blog.prototype object). While it's true that reading that property from an object created via new Blog will find it on the prototype (if the instance doesn't have its own signature property), the results of writing to the property are very, very different. Consider:
function A() {}
A.prototype.prop = "prototype prop";
var a1 = new A();
var a2 = new A();
snippet.log(a1.prop); // "prototype prop"
snippet.log(a2.prop); // "prototype prop"
a1.prop = "updated";
snippet.log(a1.prop); // "updated" -- because `a1` has its own `prop` property
// now and no longer uses the prototype's
snippet.log(a2.prop); // "prototype prop"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Contrast that with:
function B() {}
B.prop = "B prop";
var b1 = new B();
var b2 = new B();
snippet.log(b1.constructor.prop); // "B prop"
snippet.log(b2.constructor.prop); // "B prop"
snippet.log(B.prop); // "B prop"
b1.constructor.prop = "updated";
snippet.log(b1.constructor.prop); // "updated"
snippet.log(b2.constructor.prop); // "updated"
snippet.log(B.prop); // "updated"
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
For "class"-wide information, I would always use Blog.signature, not Blog.prototype.signature. I'd use Blog.prototype.signature for instance-specific default properties where the values are primitives or functions (but not non-function objects or arrays, I'd set those up in the constructor function).
Side note: You're not declaring a variable in either of your code snippets. You're adding a property to an object. In the first snippet, you're adding the property to the object that will get assigned as the prototype of objects created via new Blog. In the second case, you're adding a property to the Blog object (functions are objects). Neither is a variable, in both cases it's a property.
There are no class variables in Javascript. Actually, there are no classes altogether in Javascript. Thinking in terms of classes and static variables (are you a Java dev?) won't let you know what's going on. Even if the concept of "a class" is independent of the programming language to some degree, it is important to understand that it's not a fundamental programming construct - and in fact there are languages without classes, like Javascript.
Javascript is a very simple language: it has functions and dictionaries, and has the syntax to combine both and support programming the object-oriented way. Take this example:
var johnSnow = { first: "John", last: "Snow" };
function fullName(character) {
return character.first + " " + character.last;
}
console.log(fullName(johnSnow));
And now the OO version:
var Character = function(first, last) {
this.first = first;
this.last = last;
}
Character.prototype.fullName = function() {
return this.first + " " + this.last;
}
console.log(new Character("John", "Snow").fullName());
Finally we can answer your question: when should you set a property on a constructor and when you should use an instance?
Set the property on the instance when they should not be shared with other instances (obviously). You recognize these properties because often are used in instance methods and read with this.$name
Set the property on the constructor... never! Properties set on constructors are simply global variables. So just use global variables, possibly namespacing them (but obviously you'll need a global at some point!)
I guess it all depends on how you want to access the signature variable.
If you want an easy access to it from a Blog instance, use the prototype versions. Then you can do:
var blog = new Blog;
console.log(blog.signature);
Otherwise, you'll have to use Blog.signature or blog.constructor.signature.
I wouldn't worry about making signature an instance variable when you put it in the prototype because that's not what you're doing.
Blog.prototype doesn't get copied around -- it's not something every instance would have its own private copy of. It's a shared object that blog objects (=objects created with new Blog) will have set as their __proto__ (=Object.getPrototypeOf(blog)). __proto__ will be used to search for properties (that includes functions) that are not direct attributes of the instance.
A __proto__ can be overriden by setting an actual instance variable:
var Blog = function () {};
Blog.prototype.signature = "Original sig";
var blog = new Blog();
blog.signature === "Original sig"
//^looked up in Blog.prototype === Object.getPrototypeOf(blog) === blog.__proto__
blog.signature = "New sig"
//^set as an instance property
blog.signature === "New sig"
Blog.prototype.signature !== "New sig" //actual instance properties override prototype properties, but they don't over-write them
var blog2 = new Blog()
blog2.signature === "Original sig"
A classical object-oriented programming language such as C++/Java does a very similar thing, actually. Objects in C++/Java have properties and methods, and methods behave as if they were function pointer properties of instances, but they're not. Methods don't add any size to instances. They're all looked up in a shared place--your class's prototype if you will. The difference is, that in C++/Java the link doesn't exist at runtime (it's maintained by the compiler) and is only for methods. In JavaScript, each object has a real link to a class-shared lookup place (the object's constructor's prototype attribute), the link is accessible via either the objet's __proto__ attribute or more standardly via what you get with Object.getPrototypeOf(someobject), and it's not only for methods (like in C++/Java) but for properties as well.
The only difference between foo1 = {} and foo2 = new Bar is the fact that foo1.__proto__ == Object.prototype, whereas foo2.__proto__ == Bar.prototype. In JavaScript there are no classes and no instances, only plan objects.
Now, if you set Bar.prototype.property = "value", then looking up foo2.property first checks, whether foo2 has its own property called property. If it does not, it continues with foo2.__proto__ until it finds an object that does have an own property called property or until it gets to an object, whose __proto__ is null (usually Object.prototype).
It should now be obvious that by declaring Bar.prototype.property, you are setting up the default value, which looking up foo2.property resolves to, when it doesn't have its own property property. Setting up foo2.property in the constructor defines foo2's own property. You could call it an instance variable, but really, it's just a hash map key.

Placing instance properties in prototype constructors, good or bad?

I just finished reading this very good article on prototypal inheritance in JavaScript, but was surprised to see how vehemently the author was against having properties defined in prototypes.
A common mistake when creating objects for the prototype chain, from programmers that come from classical OOP anyway, is to define common properties high up in the chain because they exist for all instances. We feel the need to define the property as if the abstract object described an interface. Yet there is no point in defining in a prototype a property that will be present in objects that descend from it. Javascript is not like Java : you don't declare in the base objects variables that will be different to all instances of the descendants. You declare a variable only on the level where it will be defined.
Take the name property of our animals. Since every animal has a name, it's natural to consider this property as common to all, and define it in the common denominator which is the Animal prototype. The thing is, Animal has no name. A Dog instance has a name.
In Javascript, you cannot say an Animal has a name. Animal is an object, not a definition, even if we use it like so. And that object has no name property. Why then is name referred to in Animal's methods if Animal has no name? Because Animal is abstract : it is not intended to be used by itself. this, in Animal, will never refer to Animal. It will refer to whatever object descends from Animal, dino for example. And dino has a name.
If I have a very complex set of classes that have, dozens of properties in common. I don't see how it's better to duplicate those properties and the work that goes into setting them up on each instantiable derived class when the work can be done once in the base class, even if that base class was meant to be 'abstract'.
For instance:
function Analysis(args){
args = args || {};
// Extract supported init properties from args
this.description = args.description;
this.host = args.host;
this.source = args.source;
this.identifier = args.identifier;
this.vendor = args.vendor;
this.agent = args.agent;
//etc...
}
function PortfolioAnalysis(args){
Analysis.call(this, args);
args = args || {};
this.portfolio = args.portfolio;
this.author = args.author;
//etc...
}
PortfolioAnalysis.prototype = Object.create(Analysis.prototype);
PortfolioAnalysis.prototype.constructor = PortfolioAnalysis;
function TreatyAnalysis(args){
Analysis.call(this, args);
args = args || {};
this.treaty = args.treaty;
this.terms = args.terms;
//etc...
}
TreatyAnalysis.prototype = Object.create(Analysis.prototype);
TreatyAnalysis.prototype.constructor = TreatyAnalysis;
//etc...
So the article is saying I should paste the initialization code for the properties description, host, source, etc. in each of the derived classes, and remove it from the base class.
I don't see why that's better, especially if there's a bunch of complex common logic around constructing these objects using those shared properties, what's so bad about defining them in the base class, and if it's so bad, is there a way around it that doesn't involve code duplication or having to define a separate '.init()' method?
So the article is saying I should paste the initialization code for the properties description, host, source, etc. in each of the derived classes, and remove it from the base class.
No. Your code is perfectly fine, exactly how it should be done.
And that article is saying that the properties like description, host etc should be placed on instances (like a new ThreatAnalysis(…), or even a new Analysis(…)), but not on Analysis.prototype - just what you are doing. There are some people who would "default", e.g. empty, identifiers etc on Analysis.prototype because they want to "declare" that every Analysis instance should have an identifier. That is rubbish, as the article explains.
To share your initialisation behaviour in the Analysis constructor is fine (as the article mentions, shared functions may be placed hight in the prototype chain). There's no need to inline it and make Analysis and empty object, even if it is abstract and will never be instantiated directly.
I don't think you get prototypal inheritance yet. The author is not saying “don't put the initialization code in the base constructor”. What the author is saying is “don't put properties on the base prototype”. It's totally different.
So you are allowed to do what you are currently doing. It's totally fine. What you shouldn't do however is put default values of properties on the prototype as it might cause problems. For example consider:
function Foo() {}
Foo.prototype.data = []; // you shouldn't do this
var a = new Foo;
var b = new Foo;
a.data.push(0);
alert(JSON.stringify(b.data)); // [0]
This is why you shouldn't share properties on the prototype. We modified the value of a.data but since data is shared amongst all instances of Foo we also modified b.data. Hence an invariant was violated.
Think about it like this:
The properties defined on the current object are its public properties. They are not shared.
The properties defined on the prototype of the current object are static properties. They are shared amongst the instances of the prototype.
Hence it's alright to define static properties, like the count of all the instances, on the prototype. However it's not alright to define public properties on the prototype because it may cause problems like the one above.
Dr. Alex Rauschmayer explains this better: http://www.2ality.com/2013/09/data-in-prototypes.html
Your code is fine because the this in your constructors always point to the current object, not the prototype. Hence you are not defining any properties on the prototype.
I think you got confused because of constructors vs prototypes. Perhaps this blog post would elucidate your doubts: http://aaditmshah.github.io/why-prototypal-inheritance-matters/

understanding Prototype in javascript [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How does JavaScript .prototype work?
Coming from Java background, I'm trying to understand javascript.
Please let me know if these are right.
Like in java, there is a supreme Object, from which all other objects inherit.
The prototype property is like a pointer that points to the parent object (classes in java)
For "Object" object, the prototype is null.
prototype property's values are strings denoting the objects nomenclature and aren't pointers like in C. The pointer concept is implemented using the hidden attribute,[[PROTOTYPE]] that is not accessible in script.
I'm using node.js instead of browser to learn JS.
I tried,
var human = Object.create(null); // same as var human;
console.log(Object.getPrototypeOf(human)); //null
var man = Object.create(human);
console.log(Object.getPrototypeOf(man));
//{}
//expected 'human'
var person = Object.create(Object.prototype); // same as var person = {}
console.log(Object.getPrototypeOf(person));
//{}
//expected 'object'
Yes, with the exception of Object.create(null) which doesn't inherit from anything.
Not sure what "parent object" is, but the prototype of a function consists of functions that are accessible by instances. Because Object.prototype.toString exists, so does {}.toString - it is inherited.
Yes, the prototype chain ends here.
No, .prototype (or the value returned by Object.getPrototypeOf) is an object which you can extend with properties, so that those properties are inherited by instances.
Your examples:
var human = Object.create(null); // same as var human;
No, it creates an empty object that doesn't inherit from anything. var human; sets human to undefined - which is not an object but a primitive value (not everything is an object in JavaScript).
var man = Object.create(human);
console.log(Object.getPrototypeOf(man));
//{}
//expected 'human'
Object.getPrototypeOf(man) returns the object human. This is an empty object; node shows it as {}. It is not a string. In fact, objects can be assigned to multiple variables. An object does not have a variable bound to it, so by design it is not possible at all to get a string. To check equality, you could do Object.getPrototypeOf(man) === human which yields true.
var person = Object.create(Object.prototype); // same as var person = {}
console.log(Object.getPrototypeOf(person));
//{}
//expected 'object'
This is indeed the same as {} - an empty object that inherits directly from Object. As said above, the prototype is Object.prototype and not a string. It looks empty but that's because Object.prototype's functions are available by default and hidden.
First, you need to read about the create method before you attempt to use it.
Second, invoke objects in the following manner:
var human = {}, man = {}, person = {};
Third, this is not Java. In Java classes and an understanding of classes are pretty important. Prototypes are completely optional in JavaScript. The only performance benefit offered by prototypes comes when you code makes heavy reuse of functions by reference in different scopes. If this style of coding does not apply to you then you likely do not need to use prototypes.
Prototypes are inherited from the parent, or some ancestor, object. A JavaScript parser will first look for local assignments and if none exist will then examine the current object's prototype for the presence of the named reference. In a nutshell this all you need to know at this early point in writing JavaScript.
Firstly, IMO, don't start off with node. Node is going to drag you into a pool of quicksand if you don't know javascript yet. Secondly, when I started off with function based code, then OO and only then I moved to prototypes. But if you really want to know, this question has already been answered over here. Feel free to ask me if you have any more questions!

Categories

Resources