Difference of the Value, Prototype and Property

Difference of the value, prototype and property

I don't like that pattern either. They have an init function, which is the constructor of all jQuery instances - the jQuery function itself is just a wrapper around that object creation with new:

function jQuery(…) { return new init(…); }

Then, they add the methods of those instances to the init.prototype object. This object is exposed as an interface at jQuery.fn. Also, they set the prototype property of the jQuery function to that object - for those who don't use the fn property. Now you have

jQuery.prototype = jQuery.fn = […]init.prototype

But they also do two [weird] things:

  • overwriting the constructor property of the prototype object, setting it to the jQuery function
  • exposing the init function on jQuery.fn - its own prototype. This might allow Extending $.fn.init function, but is very confusing

I think they need/want to do all this to be fool-proof, but their code is a mess - starting with that object literal and assigning the init prototype things afterwards.

difference between class.prototype.property and object.property

Prototype helps you, to have kind of inheritance (prototypal inheritance).

you can add properties to your objects manually, or borrow the property from its prototype. Let's take a look to some examples:

var obj = new myClass();
obj.p2 = 'p - child';
console.log(obj.p2); // p - child

var obj2 = Object.assign(obj.__proto__); // will borrow the value from the obj prototype
console.log(obj.p2); // p - child

Now take a look to what happen with myClass prototype:

var obj3 = Object.assign(myClass.prototype); //will borrow the value from the myClass prototype
console.log(obj3.p2); // p - parent

And here an example with not existing properties:

var obj4 = new myClass();
var obj5 = Object.assign(obj4.__proto__);

obj4.p3 = 'P3 - value';

console.log(obj4.p3); // P3 - value
console.log(obj5.p3); // undefined

Note: __proto__ is for objects {}, prototype is for functions.

Hope this helps to clarify a little bit.

difference in assigning value to a property of prototype directly vs .extend

The First approach you used :

options = $.extend({
property1 : value1,
property2 : value2,
});

According to the Jquery Documentation

If only one argument is supplied to $.extend(), this means the target argument was omitted. In this case, the jQuery object itself is assumed to be the target. By doing this, you can add new functions to the jQuery namespace. This can be useful for plugin authors wishing to add new methods to JQuery.

Explaination

The options you will receive is jquery object itself. Your result option object will behave as Jquery Object and you won't be able directly access the key property1 and property2. Because you have extended the $ i.e the jQuery object itself.

You can then use option as you use $ to perform DOM manipulation or other feature as which JQuery provides. Purpose of extend is to add additional props to existing object. But if you don't provide target, it assumes it as Jquery object itself.

So now,

  options.trim(" Hello World "); // outputs Hello World without 
//leading or trailing spaces

P.S. Behaves like a $

Basic Object Assignment

options = {
property1 : value1,
property2 : value2,
};

Its just basic Javascript Object, which behaves normally. You can access the properties using the dot operator unlike in above scenario.

The same behaviour of above can be achieved if you pass a blank object as first parameter as

options = $.extend({}, {
property1 : value1,
property2 : value2,
});

Now it will behave as a normal object should, cause you have just merged your blank target object with new properties.

__proto__ VS. prototype in JavaScript

__proto__ is the actual object that is used in the lookup chain to resolve methods, etc. prototype is the object that is used to build __proto__ when you create an object with new:

( new Foo ).__proto__ === Foo.prototype
( new Foo ).prototype === undefined

Difference between __proto__ and [[ Prototype ]] in javascript

Each object's prototype is saved in the internal slot named as [[prototype]] and __proto__is just a getter/setter, defined in the Object.prototype object, to get the value of the [[prototype]] internal slot of any object.

Example:

const arr = [];

Each instance of an array gets Array.prototype as its prototype. So, in the above declaration of arr, [[prototype]] internal slot contains a reference to Array.prototype and in the following expression:

arr.__proto__ === Array.prototype  // true

arr.__proto__ gets the Array.prototype object from the internal [[prototype]] slot.

As mentioned above, __proto__ is just a getter/setter that gets the value of [[prototype]] internal slot and is only there for compatibility reasons. It shouldn't be used in modern javascript code; following two methods should be used to set/get the prototype of any object:

  • Object.setPrototypeOf()

  • Object.getPrototypeOf()


There are other internal slots, apart from [[prototype]], mentioned in the Ecmascript specification and these internal slots are not accessible by the javascript code we write.

If you need to know more about internal slots, read:

What is an "internal slot" of an object in JavaScript?

Trying to understand the difference between prototype and constructor in JavaScript

It is pretty hard to wrap your mind around this concept if you are used to the ease of extending objects in other OOP languages, but I'll do my best to explain the uses of those and what is what. I am going to assume you are familiar with other OOP languages. Correct me if I'm wrong.

All functions have the prototype Function(). They are inheriting all base functionality from Function like toString() and valueOf().

Then there is a constructor. That is what you use to initialize an object with.

p = new Foo();

So in this case we have two things.

  • A function Foo with Function as prototype(Foo)
  • A Function object with Foo() as constructor(p)

(following me yet?)

The Foo() constructor can override some base functionality of the Function constructor or leave it as it is and make good use of it.

If you are familiar with OOP principles, The prototype is the base class, the constructor your current class. In OOP the above would be class Foo extends Function

You can also start inheritance with this entire setup of prototype and constructor making more complex objects as you go whilst sharing functionality.

For example this:

// Make an object initialiser extending Function. In OOP `class Foo extends Function`

function Foo(bar) {
this.baz = bar;
}
Foo.prototype.append = function(what) {
this.baz += " " + what;
};
Foo.prototype.get() {
return this.baz
}

Now lets say we want different ways to get baz out of there. One for console logging and one for putting it on the title bar.
We could make a big thing about our class Foo, but we don't do that, because we need to do wholly different things with the new classes that are made for different implementations. The only thing they need to share are the baz item and the setters and getters.

So we need to extend it to use an OOP term. In OOO this would be the desired end result class Title extends Foo(){}. So lets take a look at how to get there.

function Title(what) {
this.message = what;
}

At this point the Title function looks like this:

  • prototype Function
  • constructor Title

So, to make it extends Foo we need to change the prototype.

Title.prototype = new Foo();
  • prototype Foo
  • constructor Foo

This is done by initializing a new Foo() object against the prototype.
Now its basically a Foo object called Title. That is not what we want because now we can't access the message part in Title.
We can make it properly extend Foo() by resetting the constructor to Title

Title.prototype.constructor = Title;
  • prototype Foo
  • Constructor Title

Now we are faced with one more problem. The constructor of Foo doesn't get initialized so we end up with an undefined this.baz

To resolve that we need to call the parent. In Java you would do that with super(vars), in PHP $parent->__construct($vars).

In Javascript we have to modify the Title class constructor to call the constructor of the parent object.

So the Title class constructor would become

function Title(what) {
Foo.call(this,what);
this.message = what;
}

By using the Function object property Foo inherited we can initialize the Foo object in the Title object.

And now you have a properly inherited object.

So instead of using a keyword like extend like other OOP languages it uses prototype and constructor.

What is the difference between an object and a prototype in prototypal programming?

The prototype is just another object to which an object has an implicit reference.

When you do:

var obj = Object.create( some_object );

...you're saying that you want obj to try to fetch properties from some_object, when they don't exist on obj.

As such, your second example would be closer to the way you'd use it. Every object that is created using Object.create(Dog) will have in its prototype chain, that Dog object. So if you make a change to Dog, the change will be reflected across all the objects that have Dog in the chain.

If the main object has the same property as exists on the prototype object, that property is shadowing that property of the prototype. An example of that would be the null values you set on properties of Dog.

If you do:

var lab = Object.create(Dog);
lab.color = 'golden';

...you're now shadowing the color property on Dog, so you'll no longer get null. You're not changing Dog in any way, so if I create another object:

var colorless_dog = Object.create(Dog);

...this one will still get the null value from the prototype chain when accessing the color property.

colorless_dog.color;  // null

...until you shadow it:

colorless_dog.color = 'blue';
colorless_dog.color; // 'blue'

So given your example:

var lab = Object.create(Dog);
lab.color = 'golden';
lab.sheds = true;

...it looks something like this:

              // labrador              // Dog
lab.color---> color:'golden' color:null
lab.sheds---> sheds:true sheds:null

lab.fetch()--------------------------> fetch: function() {
alert( this.color ); // 'golden'
// "this" is a reference to the
// "lab" object, instead of "Dog"
}

What's the difference between this.function and prototype.function?

Functions on the prototype are only created once and shared between each instance. Functions created in the constructor are created as new objects for each new object created with the constructor.

As a general rule functions should be on the prototype since they will generally not be modified for different objects of the same type, and this has a slight memory/performance benefit. Other properties like objects and arrays should be defined in the constructor, unless you want to create a shared, static property, in which case you should use the prototype.

Its easier to see the distinctions with normal objects or arrays rather than functions

function Foo(){
this.bar = [];
}
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //[]

as opposed to:

function Foo(){
}

Foo.prototype.bar = []
var fooObj1 = new Foo();
var fooObj2 = new Foo();

fooObj1.bar.push("x");
alert(fooObj2.bar) //["x"]


Related Topics



Leave a reply



Submit