What is the difference between two JavaScript objects?

I am trying to improve my JavaScript skills. I do not understand why (5) works and (2) returns an error. Not the same?

  • B.fn () // OK
  • B.fn2 () // TypeError: Object # does not have the 'fn2' method
  • var a = new A ()
  • a.fn () // OK
  • a.fn2 () // OK

    var A = function () { this.fn = function () { alert(3); } } A.prototype = { fn2: function () { alert(4); } }; var B = { fn: function () { alert(1); } } B.prototype = { fn2: function () { alert(2); } }; 
+4
source share
4 answers

(simple explanation) The prototype property applies only when using the function as constructor (using the new operator). function creates a clone of this prototype , and the keyword this inside the function is set to a clone. Properties on a clone are direct links / pointers to prototypes properties.

The literal object {} is a more powerful expression, alternative to new Object() and as such inherits properties from Object.prototype .

So:

 function ClassLike() {} ClassLike.prototype = { foo : "bar" } var instance = new ClassLike(); alert( instance.foo ); // bar 

It works because the new operator starts some operations in motion to create a new object, whereas:

 var instance = { foo : "bar" } instance.prototype = { baz : "foobar" } 

It simply adds another property (prototype) to the already created object and no process starts to actually assign / change the original prototype of the objects.

Now Mozilla has added a non-standard (IE does not support it) way of changing the prototype of already created objects via __proto__ , and there are some petitions that will add it to ES5 (EcmaScript 5). I would not use it. but it works as follows:

 var instance = {}; var parent = { foo : "bar" } instance.__proto__ = parent; alert( instance.foo ); // bar 

Another way to change the prototype of an already created object is to add Object to the prototype of the constructors (which is not recommended for many reasons). In this way:

 var instance = {}; // a more powerful alternative to `new Object()` Object.prototype.foo = "bar"; alert( instance.foo ); // bar 

All this is possible, although it is reasonable to do it ... I would say no, but opinions change, and I prefer to avoid discussions;)

In any case, just remember that the prototype property works when you are new a function , otherwise it will just become an instance property.

+1
source

a is an instance of class a , where B is the class itself. Since fn2 not defined as a static function, it will be available only to an instance of class B , and not to class B .

If you want to use B directly, you can use:

new B().fn2()

if you define B as function()

Alternatively, you can define fn2 in the same way you defined fn

+7
source

What you demonstrated is due to what I consider to be the biggest problem with OO in JavaScript: the prototype should be a property of the constructor function, not the object itself. This means that if you have one object that can easily be defined as an object literal, you still need to have a useless constructor to determine the prototype of your object.

Read this article: Prototype Inheritance in JavaScript by Douglas Crockford. Here is the relevant part:

[...] JavaScript itself conflicts over its prototype nature. In a prototype system, objects inherit from objects. JavaScript, however, lacks an operator that performs this operation. Instead, it has a new operator, so new f() produces a new object that inherits from f.prototype It is indirect to make the language seem more familiar with the classical preparation of programmers, but could not do this, as we can see from a very low opinion Java programmers have JavaScript. The JavaScript constructor template did not appeal to the classic crowd. This is also a hidden JavaScript true prototype. As a result, there are very few programmers who know how to use the language effectively. Fortunately, it's easy to create an operator that implements true prototype inheritance. This is a standard feature in my toolbox, and I highly recommend it for you.

Read the article for some ideas on how to effectively solve what you are trying to do.

0
source

Well, your answer is pretty simple. In JavaScript, only constructors have "prototypes", i.e. prototype property. Object literals, such as "{}", are not. Therefore, your number 2 will never work unless you change it as follows:

 var B = function(){ // the B constructor return this; } B.prototype = { fn2: function(){ alert(2); } } 
0
source

Source: https://habr.com/ru/post/1344745/


All Articles