A bit of confusion on how static works in javascript.
function StaticExample() {}
StaticExample.staticProp = "Hello"
console.log(StaticExample.staticProp) // "Hello"
Here I have created a function and then created a static variable staticProp (not if we can call it static though). This adds the field staticProp to the constructor field on StaticExample's prototype
Question 1: Is there a specific reason to this behaviour(field getting added to the constructor property)?
Now the constructor is rewritten as below.
StaticExample.prototype.constructor = {}
console.log(StaticExample.staticProp) // "Hello"
Even after that, when I tried to access StaticExample.staticProp, it provides the correct value of Hello
Question 2: From where the staticProp fetched, even when the constructor where it was initially added is overwritten.
StaticExample is an object. A function object, but an object nonetheless.
You assign a new property to it: StaticExample.staticProp = "Hello".
StaticExample also happens to have a property prototype.
The property StaticExample.prototype.constructor points to StaticExample.
Now, you can obviously access StaticExample.staticProp, because it's simply a property of an object that you assigned.
You can also replace the value of StaticExample.prototype.constructor with something else; now StaticExample.prototype.constructor doesn't point to StaticExample anymore. But StaticExample is still StaticExample and it still has the property staticProp that you created on it. You didn't replace the StaticExample object in any way. What you did replace was StaticExample.prototype.constructor, which is a different property of a different object.
Related
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.
Whenever I open an object details in console.log, after the attached properties or functions I always see "_ proto _". What is this and why is it always present even though I never declared anything like this in my object? I know it is related to some prototype feature but not exactly sure. Also, whereever it exists, whether plain js, jquery, or Angular.js it has the exact same 13 functions below it, viz. defineGetter, defineSetter, ...., set_proto.
Can someone explain it?
So whenever you make any object in JavaScript it inherited from Object. so a object in java script have this structure
private members
proto-Reference of the prototype of current object parent.
prototype- Reference of the current objects prototype
So if you make any object let say named as object1
var object1=new Object();
it will be inherited from Object. and have proto set to Object(you can think Object as root class).
I'm posting due to a lack of understanding of a couple of concepts and also to check if my description of this code is accurate.
First I have created parent object called contactForm. I've made this object equal to an object literal which uses literal notation that is, creating a new object with { } and defining properties within the brackets.
Then I have the init method. If you’re familiar with object orientated programming that would be the same things as your constructor method.
Now the next part is where is where I am confused. I am using jQuery to create a new element which are the button tags. Is this newly created element an object inside of the parent object called contactForm?
My second question is am I passing a parameter that sets the text to 'Contact Me!' to the contactForm object or the button element/object?
My final question - is it the case that the parameter passed to the object can also be called a property of that object?
Sorry if I haven't been descriptive enough or accurate enough with my terminology. Any succinct and clearly explained answers would be massively appreciated.
var contactForm = {
init: function() {
$('<button></button>', {
text: 'Contact Me!'
})
.insertAfter('article:first');
}
};
First I have created parent object called contactForm. I've made this object equal to an object literal which uses literal notation that is, creating a new object with { } and defining properties within the brackets.
You have an object, which is described in your code by an object literal, and assign that to the variable contactForm. Not sure why you would call it "parent".
Then I have the init method. If you’re familiar with object orientated programming that would be the same things as your constructor method.
Your object has a property named "init", which is a function - conveniently this is called "a method". However, constructors in JavaScript work a bit different - every function can construct objects when it is called with the new operator. Of course, a dedicated method to initialize is often used when singleton instances are declared (as literals).
Now the next part is where is where I am confused. I am using jQuery to create a new element which are the button tags. Is this newly created element an object inside of the parent object called contactForm?
No. What you are doing in the init function has (at first) nothing to do with the contactForm object. You are calling the jQuery function, and it returns an object on which you call the insertAfter method, and as you don't do anything with the result of that function it is garbage-collected.
My second question is am I passing a parameter that sets the text to 'Contact Me!' to the contactForm object or the button element/object?
You are passing two parameters: a string and an object. What the jQuery function does with these arguments is unknown to your code. According to the documentation (and to the code, if you really wanted to dig in), this will create a button element (wrapped in a jQuery instance) and call the text method on it.
My final question - is it the case that the parameter passed to the object can also be called a property of that object?
No. You pass parameters into a function. It might happen that the function sets them as properties of a returned object, but that depends on the function. Anyway they are not called "properties of the function object".
Could someone explain this to me in a sensible way:
function One() {}
One.prototype.obj = { key: 'value' };
One.prototype.str = 'string';
var inst1 = new One(),
inst2 = new One();
// now let’s change some things in our second instance
inst2.obj.key = 'buh!';
inst2.str = 'buh!';
// ok, so what happens to our other instance?
console.log( inst1.str ); // Yields 'string' (unaffected, expected)
console.log( inst1.obj.key ); // Yields 'buh!' (!!)
console.log( One.prototype.obj.key ); // is also 'buh!'
It seems that if a prototype contains an object, the instance you create using the new keyword has that object, but if you change it, you also change the prototype object, thus affecting all instances, like a sibling-inheritance-pattern...
Is this the way it’s suppose to work?
Actually, Javascript doesn't copy anything from the prototype. Everything you define on the prototype exists only once (on the prototype itself) and gets reused because the same prototype instance is passed to all objects.
When you access a property on an object, the object checks to see if it is defined on itself. If it is, it will return the value associated with that property. If it's not, it will delegate the call to its prototype, who will from now on be responsible for what happens. That's why "inheritance" (code reuse) in Javascript is better called delegation.
Things are a bit different for write access. If you set a property on the object, it will "shadow" the value locally. That's the reason why the str property is unaffected, it has actually been defined on the inst2 object. But if you delete inst2.str and do another console.log( inst2.str ) you will notice that it will return the old value.
PS:
If you want a way to prevent that from happening have a look at this tutorial: http://kevlindev.com/tutorials/javascript/inheritance/index.htm
I recommend reading the entire thing, but if you just want the meat see the KevLinDev.extend function in the "Creating a subclass" section.
In short, yes. Javascript does not implicitly copy objects for you, so when you create the object literal at obj, all instances of the One class simply refer to it via reference. Instead, you need to dynamically create the obj object in the constructor:
function One(){
this.obj = {key:'value'};
}
See also: javascript multidimensional object
from the page https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Details_of_the_Object_Model:
When JavaScript sees the new operator,
it creates a new generic object and
passes this new object as the value of
the this keyword to the WorkerBee
constructor function. The constructor
function explicitly sets the value of
the projects property, and implicitly
sets the value of the internal
proto property to the value of WorkerBee.prototype. (That property
name has two underscore characters at
the front and two at the end.) The
proto property determines the prototype chain used to return
property values. Once these properties
are set, JavaScript returns the new
object and the assignment statement
sets the variable mark to that object.
So basically if we have this function:
function Bee(first_name, second_name){
this.FirstName=name;
this.SecondName=name;
}
I want to know what is the difference between doing something like var bee1 = new Bee("qwe", "asd"); vs:
var bee1={};
bee1.__proto__=Bee.prototype;
var r=Bee.call(bee1, "qwe", "asd");
if(r!==undefined){
bee1=r;
}
For one thing, var bee1 = new Bee("qwe", "asd"); is cross-browser compatible. Some browsers won't let you mess around with an object's __proto__ field -- IE being one of those.
For another, it's less code, and makes more sense at first glance.
Also, in the second example, as of the first line, you've created bee1 but haven't initialized it. As of the second line, the system will consider it a Bee, but it's still not built like one. If something goes awry in the constructor, or anywhere else between creation and construction, you can end up with a half-baked Bee. This as opposed to new Bee(...), which either gives you back a properly constructed Bee or throws an exception.