Difference between prototype constructor and private property

Consider the first scenario:

function f(){
       console.log("inside the function : " + f.myVar);
}
f.prototype.myVar = 1;
var myObject = new f();
console.log("from the object : " + myObject.myVar);

      

And this is the result:

inside the function : undefined
from the object : 1

      

Question: why is myVar not available in a function? If stored in prototype objects, it must be available in f ().

Now this script:

function f(){
       console.log("inside the function : " + this.myVar);
}
f.prototype.myVar = 1;
var myObject = new f();
console.log("from the object : " + myObject.myVar);

      

And the output is:

inside the function : 1
from the object : 1

      

Question: Why do I get a different result? if 'this' refers to an object, doesn't f.myVar mean accessing myVar to myObject?

And now this script:

function f(){
       console.log("inside the function : " + f.myVar);
       console.log("inside the function using 'this' : " + this.myVar);
}
f.myVar = 1;
var myObject = new f();
console.log("from the  object : " + myObject.myVar);

      

output:

inside the function : 1
inside the function using 'this' : undefined
from the object : undefined

      

So if I set a property without using a prototype, it shouldn't be available on the instantiated objects. But if I write the script like this, it produces a weird result:

function f(){
       console.log("inside the function : " + f.myVar);
}
f.myVar = 1;
var myObject = new f();
console.log("from the first object : " + myObject.myVar);
var strangeObject = myObject.constructor;
console.log("from the strange object : " + strangeObject.myVar);

      

Output:

inside the function : 1
from the first object : undefined
from the strange object : 1

      

Where is this "f.myVar" stored? Whose variable is this? I am confused what the difference is between all the scenarios above. Full confirmation would be much appreciated.

EDIT:

The main problem is that I don't know what exactly this means:

function f(){}
f.someVar = someValue;

      

Because in other languages, a function is an abstract concept and doesn't actually exist before it is called. Now JS says that functions are objects by default. So, I must have an object like this using the script above:

{someVar : sameValue}

      

In fact, I think it should be the same as:

function f(){this.someVar = someValue;} //should create {someVar : someValue}

      

If so, every object created when "new f ()" is called must contain this "someVar", but they don't.

+3


source to share


4 answers


why is myVar not available in a function? If stored in objects the prototype is assumed to be available in f ().

It is available in a function, but not as f.myVar

, but as this.myVar

or f.prototype.myVar

.

Why am I getting different results? if 'this' refers to an object doesn't f.myVar mean accessing myVar to myObject?

The function is f

not the same as an object instance. This function is an object constructor, and using it with the keyword new

creates an instance that is a separate object from the function.

When you use f.var

it is a property var

of the function object. When you use it this.var

in a function, it is the property var

on the object instance where the keyword is used new

.

If you use f.var

then this is a property of the constructor function object, so it will be the same variable even if you create multiple instances of the object and is only accessible with f.var

.



If you use f.prototype.var

it will also be a variable that will be the same for all instances of the object, but can also be accessed using this.var

, since the object inherits from the prototype members.

Example:

function f() {
  console.log(f.var); // shows "42"
  console.log(f.prototype.var); // shows "0.01"
  console.log(this.var); shows "0.01";
}

f.var = 42;
f.prototype.var = 0.01;

      

If you want a variable to be local to every instance of an object, you shouldn't use any of them. You have to assign a value this.var

that will make it a property on the object instance.

Example:

function f(value) {
    this.var = value;
}

f.prototype.getValue = function(){
  return this.var;
};

var instance1 = new f(42);
var instance2 = new f(0.01);

// now you have two instances with separate values:

console.log(instance1.getValue()); // shows "42"
console.log(instance2.getValue()); // shows "0.01"

      

+1


source


Start by exploring the definition of a word prototype. I think it's important to keep this in mind when thinking about how new objects are created in JavaScript.

pro k type

noun

  • the first, typical or preliminary model of something, especially a machine from which other shapes are designed or copied.

verb

  • make a prototype (of a product).

A prototype is a model from which another shape will be copied.

When you create a new object in JavaScript, this is exactly what happens.

var obj = new MyObject();

      

There are many things going on in the above code, but in the context of the question, there are two things that matter:

  • The prototype is applied to the new object.
  • The MyObject function is called, with this

    a new object set.

With this knowledge in mind, let's take a look at the different forms of variable definition that you described:

function MyObject() {}
MyObject.myProperty = 'MyProperty';

      

It is important to understand that the functions themselves are objects in JavaScript. Therefore, it function MyObject

is an instance of an object for itself. In the second line, we set a property myProperty

on this function object.

Refer to the creation steps above and you will notice that it does not include applying the properties of the function object to a new instance of the object. It will only apply the prototype properties of the function object and then runs the function body with this

set to a new instance.

function MyObject() {
    this.myProperty = 'MyProperty';
}

      

Here the property myProperty

is set in a separate instance.



function MyObject() {}
MyObject.prototype.myProperty = 'MyProperty';

      

In this example, each new instance MyObject

will be assigned its own property myProperty

and value set to 'MyProperty'

. From there, each instance can change its own myProperty

to any of its values ​​without affecting the other.

function MyObject() {
    console.log('myProperty', this.myProperty); //Will output 'Outside constructor.'
    this.myProperty = 'Inside constructor.';
    console.log('myProperty', this.myProperty); //Will output 'Inside constructor.
}

MyObject.prototype.myProperty = 'Outside constructor.';

      

The example above shows how it is myProperty

first applied from the prototype and then overwritten by the value in the function being executed.


Let's look at an example with all the forms you specified:

var output1 = document.getElementById('output1'),
    output2 = document.getElementById('output2'),
    output3 = document.getElementById('output3');

function MyObject(myProperty) {
  this.myProperty = myProperty;
}

MyObject.myProperty = 'Function property.';

MyObject.prototype.myProperty = 'Prototype property.';


var obj = new MyObject('Constructor property');

output1.innerHTML = obj.myProperty;
output2.innerHTML = MyObject.myProperty;
output3.innerHTML = MyObject.prototype.myProperty;
      

<div id="output1"></div>
<div id="output2"></div>
<div id="output3"></div>
      

Run codeHide result



In the example above, you will see how each can be referenced. Now let's take a closer look at it. See what happens to your Function Property when it is set from two different object instances:

var output1 = document.getElementById('output1'),
    output2 = document.getElementById('output2');


function MyObject() {
  //We are concatenating a string to the end of the property on each function call.
  MyObject.myProperty += ' test ';
}

MyObject.myProperty = 'Function property.';


var obj1 = new MyObject();
var obj2 = new MyObject();

output1.innerHTML = MyObject.myProperty;
output2.innerHTML = MyObject.myProperty;
      

<div id="output1"></div>
<div id="output2"></div>
      

Run codeHide result


The above code demonstrates how function level property is efficiently allocated. This is because it is not part of every instance. It is part of a functional object.


Here, I'll show you the process that goes with the operator new

, without actually using the operator new

:

var output = document.getElementById('output');


//Let have an object that has a prototype property with some properties:
var MyPrototypeObject = {
  prototype: {
    myPrototypeProperty: 'Prototype property'
  }
};

//Let specify a function that will be used as a constructor:
function MyConstructorFunction() {
  this.myInstanceProperty = 'Instance property';
}


//First, new creates an object
var obj = {};

//Next, it applies all the properties from the prototype. We are using the MyPrototypeObject prototype property for this example
for (var key in MyPrototypeObject.prototype) {
  var val = MyPrototypeObject.prototype[key];
  
  //Set the same property on the new object.
  obj[key] = val;
}

//Now the prototype has been applied, let apply the constructor function that was called.
MyConstructorFunction.call(obj); //This calls MyConstructorFunction with this set to obj.

output.innerHTML = 'myPrototypeProperty: ' + obj.myPrototypeProperty + '<br>' + 'myInstanceProperty: ' + obj.myInstanceProperty;
      

<div id="output"></div>
      

Run codeHide result


+2


source


As for the question in the board, it's actually simple :-)

you have a function object function f(){}

you add a property to this object, for example you can add a property to any other object in javascript f.someVar = 1

this is not the case function f(){this.someVar = someValue;}

because this

in javascript it depends on how the function is called and can refer to the instantiated object, the global object, or whatever if called with a function call

or apply

.

When you create an object with an operator, new

you call f

as a constructor, in which case the inner function this

refers to the created object, and all properties added inside the function are this.something = val

added to the created object.

Note: that you are not using any property from the function directly, so this is not added to the created object.

As for prototype

: when creating an object, you just set the property of the prototype

created object to the object f.prototype

. So in the end when you create the object you are not using any property directly added to the function object, just a property from the prototype and a property added manually in this

in the constructor

0


source


You seem to be confused with the function and object prototype.

Here is a quote from Eloquent Javascript explaining the difference:

It is important to note the difference between a prototype associated with a constructor (via its prototype property) and prototypes have a prototype (which can be obtained using Object.getPrototypeOf). The actual prototype of the constructor is Function.prototype, since constructors are functions. Its prototype property will be the prototype of the instances created through it, not its own prototype.

0


source







All Articles