JavaScript function called object with lower-case "o" - javascript

I just watched an introductory JavaScript lecture from Douglas Crockford, in which he mentions a function called object that should be used to create a new object linked to an object as its parameter. I would guess what he means by that is that if I say
var objB = object(objA);
The objB's internal [[prototype]] reference is set to objA, although he didn't explicitly formulate it like that.
On the other hand, I have read his book, in which he doesn't mention such a function at all and instead presents his own way of creating an object from a prototype, defining following function :
Object.create = function(o) {
var F = function() {};
F.prototype = o;
return new F();
}
Essentially taking advantage of the behavior of the new operator that sets the internal [[prototype]] link of the newly created object to whatever the constructor function's prototype property points to.
My question is why would he omit a built-in function and invent his own way to do the same thing. Is the former call to object function really equivalent to
var objB = Object.create(objA);
Or is there some slight difference ?

The two functions are one and the same, and neither are built in to JavaScript. See Crockford's article describing why he switched between the different naming conventions.
Edit from the future: I saw this old answer and wanted to point out that Object.create() is indeed a native (and very important) ES5 method.

There is no difference. And here is "simplified" explanation:
The thing is, everything in javascript is an object and inherits from Object.
Also you can look at "function" as directive which defines new type of object, actually constructor of object if you are using new keyword. If you don't use new keyword and call function like in example below
function doSomething(){
alert("works");
}
javascript engine will create object doSomething which will contain prototype property, this prototype is defined type of object doSomething and it contains constructor which is created by javascript developer with code above. For bult in functions or prototypes, constructors have native code

Related

Can functions in JavaScript be called as an instance of Object?

I was recently introduced into learning JavaScript and I was literally confused when I went through the prototype concepts. Everything I read and understood got confused.
Let be get straight through..
I have two questions related to functions and Objects.
Question 1:
Can functions in JS have (key, value) pair of property in it? If so, what might me the data type of the key? Because In an Object, the key of the property can be only of the types String, Object and in some special cases Symbol.
Question 2:
How are the functions evaluated internally? Are they converted to objects?
function sample () {
// code goes here
}
and
let myFunc = new Function(,,);
Thanks
It seems your overall question is “what are functions”.
Yes, functions are objects*. That’s why they are first-class citizens. They are just like any other value. Just like other objects they can have properties (you might be familiar with f.call, f.bind, etc).
What distinguishes functions from other objects is that they have an internal [[Call]] property (internal properties cannot be accessed from user code, they are used in the specification to define internal state/behavior of objects).
The [[Call]] property contains some representation of the code in the body of the function. It’s this code that is executed when the function is called.
There are other internal properties needed for a function to work, but [[Call]] is the most important one. It is used to determine whether an object is callable or not.
Prototypes are not primarily related to functions. Prototypes are a concept applying to objects in general. They are not very complicated either: a prototype is a just an object. What makes an object a prototype is that another object has a reference to it via its internal [[Prototype]] property. Then we can say “this object is the prototype of the other object”.
Other languages work similarly. Python for example lets you make instances of classes callable by implementing the magic def __call__: method.
*: There are seven data types in JavaScript:
Boolean
Number
String
Null
Undefined
Symbol
Object
The first six are so called “primitive” data types.
You can add properties at will to a function, as in JavaScript functions are objects. In both of the syntaxes you provided for creating a function, you get a (function) object.
Example of adding properties:
function counter() {
console.log(++counter.count);
}
counter.count = 0; // create a property on the function object
// Call the function several times
counter();
counter();
counter();
As functions are objects, the same restrictions apply: property names are strings. Values can be anything. Properties are not ordered.
Answer to Question 1:
Yes, you can have key: value pair inside a function, but that function is called constructor. For example:
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
In ES6: you can store similar key:value pair using constructor() function inside a class. For example:
constructor(make, modal, year) { // constructor syntactic sugar
this.make = make;
this.model = model;
this.year = year;
}
The data-type of key depends on what type of value you're storing in that key. In our example, if I store string value in this.model, data-type of model key would be string and If I store year as a number then data-type of this.year would be number.
Answer to Question 2
To understand how a function works internally, you need to understand execution context. To understand execution context, you must read this article by David. To simply put:
Every time a function is called, a new execution context is created. However, inside the JavaScript interpreter, every call to an execution context has 2 stages:
Creation Stage
[when the function is called, but before it executes
any code inside]: Create the Scope Chain. Create variables, functions
and arguments. Determine the value of "this".
Activation / Code
Execution Stage: Assign values, references to functions and interpret
/ execute code.
My best advice would be to jump into Chrome console and play there. Really good way to fit bricks in their places.
Can functions in JS have (key, value) pair of property in it? If so,
what might me the data type of the key? Because In an Object, the key
of the property can be only of the types String, Object and in some
special cases Symbol.
Sure they can. But you misunderstood something about Object as a key. You can do this:
var obj = {};
var key = {};
obj[key] = "Smthg";
But that would work just because key would be stringified. So obj[key] would be converted into obj["[object Object]"]. Test it out:
var obj = {};
var key = {};
obj[key] = "key1";
obj["[object Object]"] = 'key2';
console.log(obj[key]);
As you see, no matter how many objects you will use as a key - they will override each other.
How are the functions evaluated internally? Are they converted to
objects?
JS is OOP language - everything is an object (except some primitives etc.). So that means there are many different objects. And they inherit something from each other, otherwise there would be a one GIANT object with all those properties bounded and endless waiting time to load your first "Hello World" application.
My probably best tool to learn JS, after taking some readings is console.dir() method (or just dir(someVar) if in console mode).
Create object - var f = new Function() and dir(f) to see what is it and what is its prototype etc.
Now its a good question , which can confuse many. First thing there is the concept of constructor and prototype in javascript
So
function A() {
console.log("A")
}
if you console.log(typeof(A)) // "function"
now A has also a protoype
console.log("Aprototype", A.prototype)
that will be an object
That native object has a property proto
console.log(A.prototype.__proto__)
This will be parent prototype. from which the current prototype is inheriting. This parent prototype will also have a constructor, That is your Function constructor
console.log("parentConstructor", A.prototype.__proto__.constructor)
Now this parent Protype has also one more proto, which is linked to Object function constructor
console.log("parent parent __proto__", A.prototype.__proto__.__proto__)
and its constructor is your Object constructor function.
Thats why you are able to get new object
var t = new Object()
Look how we have called it like constructor.
Thats how prototypical javascript is :)

understanding simple class emulator in JavaScript

Recently I started to learn a bit more advanced JavaScript (as far I only used jQuery for some simple tasks) and bought a book of Alex MaxCaw "JavaScript Web Applications". The first chapter treats about creating simple class emulator. I understand almost everything except for two lines of code marked with comments down below:
var Class = function(parent) {
var _class = function() {
this.init.apply(this, arguments);
};
if(parent) {
var subclass = function() {};
subclass.prototype = parent.prototype;
_class.prototype = new subclass();
};
_class.prototype.init = function() {};
_class.fn = _class.prototype;
//????
_class.fn.parent = _class;
//????
_class._super = _class.__proto__;
return _class;
};
Can anyone tell me what is purpose of these two lines? I'll be very thankfull.
Walking through the code:
Class is defined as a function that calls init with the arguments provided it. This means you can call it with standard constructor syntax using new eg. var instance = new Thingy() and get the init function called with the proper this value.
If you pass a parent class in, your class gets that class's prototype property added to the prototype chain of a new empty object which it uses as its prototype property. A more succinct way of doing this in modern browsers is _class.prototype = Object.create(parent.prototype);
The init function is defined. This should likely be overridden with more useful initialization code after a _class instance is created (or the code should be changed to allow the passing in of an init function when you create a Class... or allow the instance to walk the prototype chain to look for other init functions.
_class.fn is created to provide a reference to the _class constructor's prototype function.
_class.fn.parent is created to provide a reference back to the constructor. This may be useful if you are applying the prototype in some other context and want a reference back to the prototype's constructor.
_class._super is assigned the internal, non-standard __proto__ property of the constructor. Remember that constructors are functions and, in Javascript, functions are objects. This means they have their own internal prototypes. The earlier references to prototype are the prototype assigned to objects created with this constructor NOT the constructor's prototype itself. All functions inherit from Function.prototype, which is where they get bind, apply, etc. _super in this case is just a reference to Function.prototype.
As to when this type of _super is used, one could imagine doing the following:
function Maker(){ //this will be called as a constructor, ie. with new
var fun = function(){}; //Make a function
fun.__proto__ = this.__proto__; //yuck. Set the function's this value to the instance
return fun; //return the function
}
Maker.prototype={say:function(){console.log("Javascript is fun!.. And weird.")}};
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // undefined!!
Woah! What just happened?
In fact, you replaced your functions internal prototype with an Object. This allows you to build up interesting prototype chains and interact with both functions and objects in a similar way. Note, however, that the link with Function.prototype has been severed, which is why we don't have access to bind. However let's fix it with more prototype magic!
function FunctionConnector(obj){
for (var prop in obj){
if(obj.hasOwnProperty(prop){
this.prop=obj.prop
}
}
}
FunctionConnector.prototype=Function.prototype;
Maker.prototype=new FunctionConnector({say:function(){
console.log("Javascript is fun!.. And weird.")
}});
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // function bind(){ [native code] }
Now what is that FunctionConnector? It takes an object and, when called as a constructor, returns an object that both has all the properties of the passed object AND inherits from Function.prototype. As you can see, our access to bind has returned (Of course we also could have made do with our original implementation and just Function.prototype.bind.called our way to victory).
With this new pattern in hand it may be clearer what _super in your code does, namely it references the built in prototype of the _class constructor you are making (In our example the instance of FunctionConnector would be _super). This reference could be used to patch the prototype at runtime, call methods with apply or anything else you can due with a reference to an object.
This is, as you may have noticed a little hackish, especially since __proto__ is nonstandard. But it's also somewhat neat if you enjoy the patterns it allows. I'd recommend only doing something like this if you are very confident in your knowledge of Javascript inheritance, and perhaps not even then unless you are in charge of your entire code base.
From what i know, fn is just an alias to the prototype property
And about the _super, that one is for referencing to the "class" from which you are inheriting
Here's more about the use of _super and js inheritance: article

If Javascript's native OOP is classless, what about the constructor? Doesn't that imply a class?

I think Javascript native OOP system is said to be classless, and is object-based, not class-based. But every example I see always start with a constructor similar to
function Person(name) {
this.name = name;
}
Just by using a constructor this way, doesn't this already imply a class is being used? (a class called Person)
Details:
If we can use
a.__proto__ = b;
on any Javascript platform, then I think it is classless. But we can't do that. If we want that behavior, we need to use
function F() { }
F.prototype = b;
a = new F();
and so, a constructor has to be used. So if constructor is such a cornerstone in Javascript, that means it is intended to be constructor of Person, Widget, etc, and these are classes.
The OOP in Javascript is slightly different from, for instance, the Java OOP.
The Javascript constructors do not refer to a class definition (so it is classless). Rather the constructor refers to a prototype. The base of the OOP in Javascript is the Object object (not the Object class), from where all the others objects are derived.
Prototyping grants you inheritance, and the possibility to extend an existing object with properties and methods.
I suggest you this article.
In your example:
function Person(name) {
this.name = name;
}
Mike = new Person('Mike');
the Person() function lets you create a new object prototyped on the Object object with a new property called name. Well, such a kind of function in Javascript oop is called a constructor.
Classless may be an inaccurate way to describe JavaScript's approach on OOP.
JavaScript does lack class definitions.
It also lacks a class-to-object correspondence.
You can't check if an object instantiated with a constructor such as Person is of class Person.
You can check if it contains the expected object members and conclude that it is of the expected class.
But if the object members have been changed along the way you're not going to get the desired/expected result.
TL;DR
JavaScript exposes constructors (appropriately named prototypes) as a manner in which you can define a template for constructing plain objects.
The important thing is that the end result of a prototype call is a plain object with some predefined members and not an object of a certain class .
It's good to think of javascript as a classless environment. If you think javascript classes you should be able to assume there's certain useful things you can do when there are classes and they're strictly enforced. However those certain useful things you cannot assume. The presence of something that looks like a constructor does not indicate you're creating a class.
For example, let's say you var dude = Person('Ashton Kutcher'). Now, when you dude instanceOf person, you get true. You assume you have the properties and methods of a person. What if some code comes along and says dude.personMethod = undefined. Now, while dude instanceOf person will still be true, the personMethod is no longer available.
You can think of javascript as having classes but it's a leaky abstraction. It's better to think of javascript as having a prototypal inheritance system when it comes to determining what something is and what you can expect of it.
More information here: http://javascript.crockford.com/prototypal.html
Create a class using the Object Constructor and prototyping can help us
in creating many instances of the class without redefining the object each time wee need it.
so in the above example
function Person(name)
{
this.name = name;
}
you can create two persons with different names.
example :
var personA = new Person();
personA.name = "james";
var personB = new Person();
personB.name = "Tom";
alert(personA.name + personB.name);
i suggest you reading this link will be helpful
http://www.javascriptkit.com/javatutors/oopjs2.shtml

Is it possible to create a function where [[prototype]] refers to another function

I would like to create function objects (yes, all functions are objects) with some control over the prototypal inheritance, that is, I would like one function to inherit from another.
I can make objects that have prototypal inheritance, and know to set the prototype property of a function performing as a constructor to initialize the [[prototype]] property of the object.
However, when creating a function, I must use the function operator or the Function constructor. I could try to swizzle Function.prototype, but (1) don't know if that is writable, and (2) that just seems quite dangerous [still, I should try doing that].
btw: I only care to do this for V8 within node.JS, so if there are means that work only for that environment, that would be acceptable.
For the record, I have seen this:
Is it possible to create a function with another prototype than Function.prototype?
In V8 (and most other browsers/engines except IE) you can change an object's prototype by setting the __prototype__ __proto__ attribute. Setting the prototype attribute will instead change the prototype that is used to create an object if the function is invoked as a constructor function. This should not be what you want.
Afaik there currently is no standard conform way to directly "subclass" a function (or array for that matter). There's only Object.create, but there is no Function.create or Array.create.
EDIT: I just realized that function objects do not have the __prototype__ attribute and changing / setting it will not turn an object into a function.
I believe though that I just recently watched a talk by Brendan Eich (the creator of JavaScript) in which he talked about Function and Array equivalents of Object.create. And infact, googling for "Function.create brendan eich" reveals the following blog post by Eich in which he talks about his wish to implement Function.create and Array.create.
EDIT 2: Ok, I screwed up. Pretty much. The non-standard attribute is of course __proto__ and not __prototype__. Setting __proto__ works fine for functions with some restrictions, which are:
To be able to call aFunction you must initialize it with an actual function, eg:
var aFunction = function () {};
This is important. Calling a function does not access the prototype chain, so if you define aFunction as an object and simply set the __proto__ attribute, you will not able to call aFunction.
You can now assign any other function to aFunction.__proto__ and reading any members (including methods) will correctly delegate to the prototype chain if the porperty is not found on aFunction itself.
Calling aFunction() will always invoke the function that was originally declared when aFunction was defined and will never invoke aFunction's prototype function. So the body of the function is not subject to inheritence.
Sorry for screwing up first with the name of the attribute. Hope this helps you nevertheless.
I came up with a solution that solves my needs. It is not cross-browser, but can be used cross-browser. My most important use case is as a module for node.JS. In that case, the mechanism of setting __proto__ works just fine, in which case I can call methods on the base function object
f.method(args...);
and it executed by code in the "super" function. Because the method is invoked by the method invocation pattern, "this" is set to the base function object, and so the proper properties are accessed even though the method resides in the "super."
Now for the in-Browser case: when I use my library client-side, I provide a proxy mechanism. Alas, code intended for the browser must be written differently. The invocation is:
f.proxy(methodName, args...);
The proxy method in the base function object is:
f.proxy = function (methodName) {
var p = this.constructor.prototype;
return p.proxy(this, methodName, arguments);
};
The proxy in the "super" object's prototype is:
proxy: function (instance, methodName) {
var args = Array.prototype.splice.apply(arguments, [2]),
method = this[methodName];
return (method) ? method.apply(instance, args) : undefined;
}
I probably should have named this "forward" or some such, but "proxy" is good enough.
Perhaps this mechanism might be useful to someone...
I think I understand what you're trying to do. In short, there's no way to really do it natively. You'd have to access the Function constructor, which for function expressions and definitions (i.e. anything using the 'function' keyword), isn't possible as far as I can tell. You could overwrite Function and just always use new Function([args], string) but I doubt you (or any JS programmer) want to do that.
Your best bet would probably be to send your function expressions to another function that returns the function object with your custom methods dynamically added:
wrapFunc = function(f){
f.customFunc = someCustomFunc;
return f;
}
var myNewFunc = wrapFunc(
function(){
//do something
}
);
myNewFunc.customFunc();

How does an object reference itself in Javascript?

I was experimenting with inheritance in javascript, and wrote those two functions:
Object.prototype.inherits=function(obj){this.prototype=new obj;}
Object.prototype.pass=function(obj){obj.prototype=new this;}
This code works very well:
Dog.inherits(Animal);
But the following fails:
Animal.pass(Dog);
As I understand it, my pass functions doesn't work, because "this" isn't a reference to the object instance itself? If that's the case, how can I reference the object from within itself?
Thanks in advance!
Well, actually the two are doing exactly the same:
Dog.prototype = new Animal;
The this value inside the methods will refer to the base object where the reference was invoked, in the case of:
Dog.inherits(Animal);
The this value will refer to the Dog constructor function, and the obj argument will be the Animal function.
When you call:
Animal.pass(Dog);
The this value will refer to the Animal function, doing at the end exactly the same thing as the inherits method, but the other way around.
I would recommend you to not extend the Object.prototype object, because it can cause you a lot of problems, for example those two properties will be enumerated in any for-in loop, e.g.:
for (var prop in {}) { // <-- an empty object!
alert(prop); // will alert 'inherits' and 'pass'
}
All objects inherit from Object.prototype, and it seems that you intend to use those methods only on Function objects, it would be safer to extend the Function.prototype object, or implement the methods as functions that take two parameters.
Works for me, with test code like:
function Animal() {}
Animal.prototype.isanimal= 1;
function Dog() {}
Animal.pass(Dog);
Dog.prototype.isdog= 2;
alert(new Dog().isanimal); // 1
alert(new Dog().isdog); // 2
However, bear in mind that new this or new obj will call the function this/obj, creating a new full instance. If you have constructor code in that function that expects to receive some arguments, or sets up instance state, you can end up with problems. To create a new this without calling this as a function you can use a different constructor that does nothing:
function nonconstructor() {}
nonconstructor.prototype= this.prototype;
obj.prototype= new nonconstructor();
Also, you should avoid prototyping onto Object. This will cause trouble for code using Object as a general-purpose lookup map. As you only seem to be working with constructor-functions, prototyping onto Function should meet your needs and is much safer.

Categories

Resources