Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between prototype function and json notation function?

I have created below two employee classes, one using a constructor function and the other with JSON notation. In the constructor function, the print function is created by prototype so only one copy will be kept and objects (emp1 and emp2) share this print function.

Question: In the JSON notation (EmployeeNew), will the print function be held in memory as one copy only? Or will each object keep its own copy? What is the fundamental difference between these two approaches? Which is best for which scenario?

var Employee = function (name) {
    this.name = name;
};

Employee.prototype.print = function () {
    console.log(this.name);
}


var emp1 = new Employee("jack"),
    emp2 = new Employee("mark");

emp1.print();
emp2.print();

var EmployeeNew = {
    init: function (name) { this.name = name; },
    print: function () {
        console.log(this.name);
    }
};

var empNew1 = Object.create(EmployeeNew),
    empNew2 = Object.create(EmployeeNew)

empNew1.init("jack")
empNew1.print();
empNew2.init("jack");
empNew2.print();
like image 362
user845392 Avatar asked Feb 26 '26 14:02

user845392


1 Answers

Your two code examples are generally equivalent (except for some minor details not relevant to the question).

This...

Object.create(EmployeeNew)

...creates a new object with the EmployeeNew object as its prototype. So the print and init functions are shared.

console.log(empNew1.init === empNew2.init); // true
console.log(empNew1.print === empNew2.print); // true

To further illustrate, here's an example that takes the following steps...

  1. Create an EmployeeNew object to be used by Object.create
  2. Create 2 unique objects using Object.create
  3. Verify that the new objects can use the functions provided by EmployeeNew
  4. Add a new function to EmployeeNew
  5. See if the objects from step 2 can use that new function

Step 1: Create an EmployeeNew object

var EmployeeNew = {
    init: function (name) { this.name = name; },
    print: function () {
        console.log(this.name);
    }
};

Step 2: Create 2 unique objects using Object.create

var empNew1 = Object.create(EmployeeNew),
    empNew2 = Object.create(EmployeeNew)

Step 3: Verify that the new objects can use the functions provided by EmployeeNew

empNew1.init("jack");
empNew1.print();
empNew2.init("jack");
empNew2.print();

Step 4: Add a new function to EmployeeNew

EmployeeNew.foo = function() {
    console.log( 'Foo was invoked' );
};

Step 5: See if the objects from step 2 can use that new function

empNew1.foo();  // logs 'Foo was invoked'
empNew2.foo();  // logs 'Foo was invoked'

So you can see that empNew1 and empNew2 are able to observe changes to EmployeeNew. This is because when we passed EmployeeNew as the first argument to Object.create, we created a new object with EmployeeNew set as the prototype of that object.

In simpler terms, when we look up a property, for example on empNew1, if empNew1 doesn't have that property, it automatically looks to its prototype to see if the property exists on that object. If so, it uses it.


With respect to your comment...

"...suppose, if create this.name as property ( name : "") is the name property also will be treated as prototype..."

Yes, if we do this...

EmployeeNew.name = "unknown"

...then that property will be shared among all instances that have EmployeeNew as their prototype object.

BUT

Because the .name property on the prototype is an immutable primitive value (a string), if we try to write to that property, what happens is that the .name property is automatically added directly to the instance.

Continuing with the example above...

EmployeeNew.name = "unknown";

Now the previously created instances will reference that property...

empNew1.name;  // "unknown"
empNew2.name;  // "unknown"

...but now lets update the property on one instance...

empNew1.name = "bubba";

empNew1.name;  // "bubba"
empNew2.name;  // "unknown"

This is because empNew1 now has its own .name property that references "bubba". This shadows the .name property on the prototype of empNew1, so the search for that property never extends into the prototype object.

Since empNew2 wasn't assigned a .name, it still looks to its prototype for that property.

like image 146
3 revsuser1106925 Avatar answered Feb 28 '26 05:02

3 revsuser1106925



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!