4

I am learning javascript and would love help understanding the snippet of code.

From Object.DefineProperties definition, the first parameter is an object. Is MyObjectConstructor a declaration or an object. With a constructor function I would expect to call new to make it an object.

This is what is confusing me. Or as I read in Javascript functions are objects so do I treat it as an object and the this property is where all staticProps and instanceProps are added to?

var _prototypeProperties = function (child, staticProps, instanceProps) {
   if (staticProps){ 
       Object.defineProperties(child, staticProps)
   };
    if (instanceProps) { 
     Object.defineProperties(child.prototype, instanceProps);
   }
  };

function myFunction() {
    function MyObjectConstructor(element) {
      this.element = element;
      this.initialized = false;
    }

  _prototypeProperties(MyObjectConstructor, {...}, {...});
}
JD.
  • 15,171
  • 21
  • 86
  • 159

3 Answers3

1

Yes, (constructor) functions are objects as well in javascript, and you can add properties directly to them.

The _prototypeProperties function in your example snippet does put the staticProperties on the constructor, so that they could be accessed as MyObjectConstructor.myStaticProperty. It also does put instanceProps (better: "class properties", "prototype properties") on the MyObjectConstructor.prototype object, from where they are inherited by instances: (new MyObjectConstructor).myPrototypeProperty. Lastly, your MyObjectConstructor does put "real" (own) properties on the instances, specifically (new MyObjectConstructor).element and .initialised.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you Bergi, with your reply and others a lot more is clear. Okay, functions are first class objects. So what is the 'this' value? Do a function has its own 'this' value? – JD. Apr 18 '15 at 20:55
  • No, `this` is a special identifier (variable?) that is set by the caller of the function. If you call the function as a constructor, `this` will refer to the new instance; so `.element` and `.initialised` will be created as own properties of the new object by the constructor. Read more about `this` [on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) or [on SO](http://stackoverflow.com/q/3127429/1048572) – Bergi Apr 18 '15 at 21:06
  • Can you look at : https://github.com/PWKad/aurelia-samples/blob/master/src/chord-diagram.js. Are you saying that outside of this file, 'this' has been set? – JD. Apr 18 '15 at 21:12
  • What do you mean by "outside of the file"? `this` is only used in functions/methods usually. Where it points to the object that the method was called on, e.g. when you invoke `obj.method()` then inside `function method(){…` the `this` value is `obj` – Bergi Apr 18 '15 at 21:16
  • Sorry, it is clearer now what you mean. Thank you so much for your help. – JD. Apr 18 '15 at 21:20
1

first : the function is the first type object in the javascript . it means you can deliver the function as value . for example :

function test(){

    return function(){
        console.log('function');
    }
}

test()();

you return the function as return an object , function can be assigned and the function another kind of value !

var test = function(i) {
    // body...
    return i;
}

test('123');

a character string 'test' refer to a Anonymous function , you can understand that you transmit a function to a character string .

second : if you use new to create a instance via function , this function will be called construction function , normally it used to init the params , and the instance will take the construction function own property or method and prototype's property or method from the construction function .

third : the instance's property of "__proto__" is refer to the construction function's prototype object . this is why the instance can use the prototype's property or method from the construction function .

forth : if you create the instance by new , the this will refer to the instance object ! so that instance can use the property and method .

from your code :

var _prototypeProperties = function (child, staticProps, instanceProps) {
   if (staticProps){ 
       Object.defineProperties(child, staticProps)
   };
   // the properties from the own construction function  , like this :
   //  this.element = element;
   //  this.initialized = false;


    if (instanceProps) { 
     Object.defineProperties(child.prototype, instanceProps);
   }
  };

  // the properties from the construction function's prototype object . like this :
  //   MyObjectConstructor.prototype.name = 'somebody';
  //   MyObjectConstructor.prototype.getName = function(){
  //        return this.name;
  //   }
qianjiahao
  • 399
  • 1
  • 3
  • 10
  • "*the first type object*" - what does that mean? – Bergi Apr 18 '15 at 16:09
  • for example : function test(){ return function(){ console.log('function'); } } test()(); you can return `function` as return `object` , the `function` can be delivered as the object in the javascript – qianjiahao Apr 18 '15 at 16:25
  • Yes, functions are objects; though "function as the object" doesn't make much sense. Your statement "*the function is the first type object in the javascript*" just doesn't parse with my English grammar. – Bergi Apr 18 '15 at 16:31
  • sorry , actually i am a china guy , and my english is not good enough , i edit the answer , maybe you can get it from my answer ... – qianjiahao Apr 18 '15 at 16:41
  • I think @qianjiahao means "first class object" – cssimsek Apr 18 '15 at 20:30
  • @qianjiahao : Thank you for the information you provided. It has helped me immensely. – JD. Apr 18 '15 at 21:47
1

In JavaScript, once defined, the resulting functions act identically:

function Hat() { }
var Hat = function() { }

Conventionally the first is used to create objects (usually with new) and the second is used as a regular method.

The new operator, when preceding a function gets kinda weird. Using the new operator will:

  • create a new Object "it"
  • set the function being called as "it"s prototype
  • binds "it" to this within the function
  • overrides the return value of the function with "it". This overrides both explicit returns and implicit returns of undefined.

For example:

// first define Hat function
function Hat() { this.color = 'red' }

// calling with `new` implicitly returns a new object bound to the function
new Hat()
// > Hat { color: "red" }

// invoking without `new` implicitly returns `unefined`,
// but `this` points to Hat's parent object.
// If running in the browser, Hat's parent object would be `window`
// so now Window.color is set to "red"
Hat()
//> undefined
Window.color
//> "red"

Be careful with new, because the new object will be returned instead of any explicit returns.

var color = function() { return "blue" }
color()
//> "blue"
new color()
//> color {}

JavaScript is prototypal by nature. The new operator reflects neither prototypical nor classical inheritance. I avoid it when possible, although many popular libraries use it.

I recommend reading through Crockford's explanation of JavaScript's prototypal inheritance: http://javascript.crockford.com/prototypal.html

Its terse, but if you understand his 10 lines of demo code you'll be good.

Play with bind, call and apply, and different scoping contexts too. After understanding scoping and the prototypal nature, the rest is just syntax.

Matthew
  • 3,510
  • 2
  • 23
  • 24
  • 2
    Thanks, @Bergi, edited. Its hard to gauge the right depth in answers, especially to someone new to a language. – Matthew Apr 18 '15 at 16:15
  • @Matthew. Thank you for the information you provided. Your 'this' example made perfect sense. – JD. Apr 18 '15 at 21:46