isPrototypeOf() function on primitive - javascript

Mozilla.org states that
The isPrototypeOf() method checks if an object exists in another object's prototype chain.
When I create a primitive variable, say
var a = 0;
And check for its [[Prototype]] (not a.prototype),
console.log(a.__proto__); //on chrome
It prints Number {0, isDivisibleBy2: ƒ, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, …}. Apparently, this value seems to be what's inside the Number.prototype.
So, I expect Number.prototype.isPrototypeOf(a); to return true, since Number.prototype does indeed exist within the prototype chain of a (the __proto __ chain).
But instead, theboutput for Number.prototype.isPrototypeOf(a); is false.
var a = 0;
console.log(a.__proto__);
console.log(Number.prototype);
console.log(Number.prototype === a.__proto__);
console.log(Number.prototype.isPrototypeOf(a));
I think I might be misunderstanding something... I believe that value.__proto__ is the right way to access the prototype chain (understang from this mozilla link). Is it just that isPrototypeOf() does not work on primitive?
Can someone help me clear up and understand this weird phenomenon?

JavaScript is actually creating a new Number object from the primitive when you access a property on it or call a method, after which the new object is promptly thrown away. That is why you can access the __proto__ property. The primitive, however, is not a Number object.

As you can see in the spec here, the first rule of isProtoTypeOf is "If Type(V) is not Object, return false" (Where V is the value passed to the method).

Related

What is differnce between Object and Function [duplicate]

Why in JavaScript do both Object instanceof Function and Function instanceof Object return true?
I tried it in Safari WebInspector.
It took a while for me to figure out but its really worth the time spent. First, let us see how instanceof works.
Quoting from MDN,
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
[instanceof]
Now, let us see how instanceof is defined by ECMA 5.1 Specification,
The production RelationalExpression: RelationalExpression instanceof ShiftExpression is evaluated as follows:
Let lref be the result of evaluating RelationalExpression.
Let lval be GetValue(lref).
Let rref be the result of evaluating ShiftExpression.
Let rval be GetValue(rref).
If Type(rval) is not Object, throw a TypeError exception.
If rval does not have a [[HasInstance]] internal method, throw a TypeError exception.
Return the result of calling the [[HasInstance]] internal method of rval with argument lval.
First the left and right hand side expressions are evaluated (GetValue) and then right hand side result should be an Object with [[HasInstance]] internal method. Not all objects will have [[HasInstance]] internal method, but functions. For example, the following will fail
console.log(Object instanceof {});
# TypeError: Expecting a function in instanceof check, but got #<Object>
[[HasInstance]]
Now, let us see how [[HasInstance]] has been defined in the ECMA 5.1 specification,
Assume F is a Function object.
When the [[HasInstance]] internal method of F is called with value V, the following steps are taken:
If V is not an object, return false.
Let O be the result of calling the [[Get]] internal method of F with property name "prototype".
If Type(O) is not Object, throw a TypeError exception.
Repeat
Let V be the value of the [[Prototype]] internal property of V.
If V is null, return false.
If O and V refer to the same object, return true.
It is so simple. Take the prototype property of F and compare it with the [[Prototype]] internal property of O until it becomes null or prototype of F is the same as O.
[[prototype]] internal property
First let us see what is the [[prototype]] internal property,
All objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. Whether or not a native object can have a host object as its [[Prototype]] depends on the implementation. Every [[Prototype]] chain must have finite length (that is, starting from any object, recursively accessing the [[Prototype]] internal property must eventually lead to a null value).
Note: We can get this internal property with the Object.getPrototypeOf function.
prototype property
[[HasInstance]] also talks about another property called prototype, which is specific to the Function objects.
The value of the prototype property is used to initialise the [[Prototype]] internal property of a newly created object before the Function object is invoked as a constructor for that newly created object.
This means that, when a function object is used as a constructor, a new object will be created and the new object will have its internal [[Prototype]] initialized with this prototype property. For example,
function Test() {}
Test.prototype.print = console.log;
console.log(Object.getPrototypeOf(new Test()) === Test.prototype);
# true
Actual problem
Now let us get back to the actual question. Lets take the first case
console.log(Object instanceof Function);
# true
It will fetch Function.prototype first and it will try and find if that object is in the prototype hierarchy of Object. Let us see how that turns out
console.log(Function.prototype);
# [Function: Empty]
console.log(Object.getPrototypeOf(Object));
# [Function: Empty]
console.log(Object.getPrototypeOf(Object) === Function.prototype);
# true
Since the Function.prototype matches the Object's internal property [[Prototype]], it returns true.
Now lets take the second case
console.log(Function instanceof Object);
# true
console.log(Object.prototype);
# {}
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
Object.getPrototypeOf(Object.getPrototypeOf(Function)) === Object.prototype
# true
Here, first we get the Object.prototype, which is {}. Now it is trying to find if the same object {} is there in the Function's prototype chain. Immediate parent of Function is and Empty function.
console.log(Object.getPrototypeOf(Function));
# [Function: Empty]
It is not the same as Object.prototype
console.log(Object.getPrototypeOf(Function) === Object.prototype);
# false
But the [[HasInstance]] algorithm doesn't stop there. It repeats and gets up one more level
console.log(Object.getPrototypeOf(Object.getPrototypeOf(Function)));
# {}
And this is the same as Object.prototype. That is why this returns true.
From MDN:
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
Essentially, it is checking if Object (not an instance of Object, but the constructor itself) has as an instance of Function.constructor somewhere up its prototype chain.
And, indeed:
> Function.__proto__.__proto__ === Object.prototype
true
> Object.__proto__ === Function.prototype
true
This explains why Object instanceof Function as well as the reverse.
ALL objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance. If you try to look up a key on an object and it is not found, JavaScript will look for it in the prototype chain.
The Function constructor creates new Function objects (instances of Function constructor). The prototype property is specific to Function objects. The Function constructor is itself a Function object (instance of Function constructor).
When a Function object is used as a constructor, a new object will be created and the new object will have its [[Prototype]] initialized with the prototype property of the constructor.
function Dog () {}
var myCrazyDog = new Dog();
myCrazyDog.__proto__ === Dog.prototype // true
The language spec is that all objects are instances of Object constructor, and all functions are instances of Function constructor.
Object instanceof Function is true because Object is a function and thus is an instance of Function (Object is a Function object - an instance of the Function constructor). Object inherits from Function.prototype.
console.log(Object instanceof Function) // true
console.log(Object.__proto__ === Function.prototype) // true
Object instanceof Object is true because Object inherits from Function.prototype. Since Function.prototype is an object, it inherits from Object.prototype.
Function instance of Object is true because Function inherits from Function.prototype. Since Function.prototype is an object, it inherits from Object.prototype.
The prototype chain looks like this:
Object ---> Function.prototype ---> Object.prototype ---> null
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Object instanceof Object) // true
console.log(Object.__proto__ === Function.prototype) // true
console.log(Object.__proto__.__proto__ === Object.prototype) // true
console.log(Function instanceof Object) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
Function instanceof Function is true. Function is an instance of itself (naturally, since it’s a function, and thus an instance of Function). The prototype chain looks like this:
Function ---> Function.prototype ---> Object.prototype ---> null
console.log(Function instanceof Function) // true
console.log(Function.__proto__ === Function.prototype) // true
console.log(Function.__proto__.__proto__ === Object.prototype) // true
Thus keep in mind that the Function() and Object() constructors are functions. Since they are functions they are instances of the Function() constructor and inheriting from Function.prototype.
Since Function.prototype is an object, Function.prototype is an instance of Object, thus inheriting from Object.prototype.
console.log(Object instance of Function) // true
console.log(Function instance of Function) // true
console.log(Function.prototype instanceof Object); // true
The source of the confusion in your question lies in the inherent dual nature of functions* in JavaScript (ECMAScript).
Functions in js are both regulars functions and objects at the same time. Think of them as algorithmic Dr. Jekyll and Mr. Hyde. They look like objects on the outside but inside they're just your good old js functions with all their quirks, or maybe it's the other way around!
JavaScript is really a tricky business :)
So back to your question, borrowing the syntax appearing on MDN:
object instanceof constructor
Applying it on the first statement in your code:
Object instanceof Function
Here you have Object, a constructor function that's used as an object initializer but since functions lead a double life in js, it has object-specific props and methods attached to it rendering it effectively an object too.
So, the first condition in the statement has been met. We remain to investigate the other condition or operand.
Function as you might have noticed is also function constructor but its other object side is of no interest to us now during the execution of this particular statement.
So, the syntactic conditions are both met namely "object" and "constructor". We can now then proceed to investigate their hereditary relation and if there's a connection between them.
Since Object is a working function itself, it makes a lot of sense to assume that it has its internal prototype prop pointing to the Function.prototype object reference since in js ALL functions inherit their props and methods through that same location Function.prototype.
true is definitely the ONLY expected outcome of this comparison performed by the instanceof operator.
For the other case:
Function instanceof Object
Since we established already that functions in js have also an object side to them. It makes sense that they got their fancy object-specific toys from the Object.prototype, and therefore they constitute instances of the Object constructor.
Hope I didn't add to the confusion with my explanation and allegories. :)
*: Not only functions that lead a double life in js. Almost all data types in js have an object dark side to them that facilitate completing operations and manipulations without any hassle.
The most badass property is actually that Function is an instance of itself. Function instanceof Function returns true.
It is nicely explained in Kannan's The Surprisingly Elegant Javascript Type Model, at http://web.archive.org/web/20140205182624/http://vijayan.ca/blog/2012/02/21/javascript-type-model
Quote at the end of the explanation:
Yes, this means that Function is an instance of itself (naturally, since it’s a function, and thus an instance of Function). This is something we’ve all been dealing with, knowingly or not, for a long time now – all constructor functions are regular functions and thus instances of Function, and Function itself is just the constructor function for constructing other functions, so it too is an instance of Function.
Very Simple Explanation, Different from all answers
Both Object and Function are constructors(type of both with return "Function objects") and both are created from Function Constructor.
The __proto__ property of both these point to 'Function.prototype' object.
QUICK EXPLANATION: __proto__ property of an object(say p1 which is Person type) points to the Constructor's protoype(say Person.prototype)
Again the __proto__ in the prototype chain points to the object "Object.prototype".
BEFORE READING FURTHER PRINT DETAILS ON CHROME CONSOLE console.dir(Object), console.dir(Function)
KEEP IN MIND, function constructors and also objects so you will see both .prototype and __proto__ properties. In all the instance objects(say p1) you will only find the __proto__ property. The __proto__ is accessor for hidden property [[Prototye]] and best way to get is Object.getPrototypeOf(p1) as __proto__ is depricated.
(p1 instanceof Person) here operator checks if the Constructor Person's prototype is in the prototypal chain of the object p1. take a note that first value is instance object(p1) and second value is a constructor (Person).
Lets analyze => Function instanceof Object.
Function object's __proto__.__proto__ points to Object.prototype , So its true
Lets analyze => Object instanceof Function.
Object object's __proto__ points to Function.prototype, So its true
Hope this helps.
Object is a built-in constructor function for objects. It is therefore a function (an instance of Function). Functions are objects in JavaScript, it is therefore an object too (an instance of Object).

If a property of an Object is not found (Obj Constructor) return value is Not undefined. Why?

Consider a basic example where I am trying to ask for a property which doesn't exist in an object
CASE-I: (General Object)
var obj1 = {
name: "Jack",
age: 29
}
console.log(obj1.city);
Answer: undefined
This means that if there is a property which is not present, it is rightly referred to as undefined.
CASE-II: (Object Constructor)
Now, I am going to do the same - first making a string which inherits from String Constructor which inherits from Object Constructor. The __proto__ of Object-Constructor doesn't have a property named __proto__ so the answer should be undefined. But rather (strangely) it returns null. Which is beyond understanding.
As far as I know, if the property of an Object is not found - its value should be `**undefined**` and not `**null**`.
Now, someone please help out in understanding - that after going up the prototype chain the concepts and implementations should remain the same. So, if the __proto__ property of Object Constructor is not found, Why the answer should not be undefined but rather null ???
The way Javascript was designed, null is at the top of the prototype chain of every object. As the specification says, for the internal method GetPrototypeOf, its type signature is ( ) → Object | Null, and it:
Determine the object that provides inherited properties for this object. A null value indicates that there are no inherited properties.
Accessing the __proto__ property of an object, or using Object.getPrototypeOf will invoke that internal method. The __proto__ property does exist on most objects (so it doesn't return undefined), but the object it's called on is not guaranteed to have an internal prototype (and if it doesn't, that operation returns null).
See how __proto__ is a getter/setter on Object.prototype:
console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'));
That property will exist for any object that goes through Object.prototype, which most do. The getter may return null.
Note that if you create an object which does not inherit from Object.prototype, the __proto__ property will not be in the prototype chain, and you'll get undefined:
const obj = Object.create(null);
console.log(obj.__proto__);

airnb/javascript: What does this mean: "These methods may be shadowed by properties ..."?

I try to understand the following sentence at github airnb/javascript
https://github.com/airbnb/javascript#objects--prototype-builtins
Why? These methods may be shadowed by properties on the object in
question
What is meant with "shadowed" in this case?
For easier reference here the full section:
3.7 Do not call Object.prototype methods directly, such as hasOwnProperty, propertyIsEnumerable, and isPrototypeOf.
Why? These methods may be shadowed by properties on the object in
question - consider { hasOwnProperty: false } - or, the object may be
a null object (Object.create(null)).
// bad
console.log(object.hasOwnProperty(key));
// good
console.log(Object.prototype.hasOwnProperty.call(object,key));
// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
/* or */
import has from 'has';
// ...
console.log(has.call(object, key));
When you creating an object
const anObject = {};
it almost always has the Object in prototype chain. It allow the created object to have access to functions defined in Object like hasOwnProperty.
Shadowed means a method or a property that defined in the created object has the same name as those functions or properties that in prototype chain.
Example of shadowing:
const obj = {};
obj.hasOwnProperty // => ƒ hasOwnProperty() { [native code] }
obj.hasOwnProperty = 'don\'t do this!';
obj.hasOwnProperty // => "don't do this!"
Consider some example below:
const object = { hasOwnProperty: false }
console.log(object.hasOwnProperty(key)) // Error: hasOwnProperty is not a function
or
const object = null
console.log(object.hasOwnProperty(key)) // Error: Can not read property of null
So you can understand shallowed in this case is your object methods in prototype is shallowed by an object property (has the same name)
See an example. Here I have created an function with name hasOwnProperty directly on the my object. So it hides the parent version of the hasOwnProperty. In it I write a logic which will return everytime true. So anybody who will use my object and tries to detect if it has some property in it (he/she doesn't know I have shadowed the base on) he can have a logic errors in his/her code. Because JS will try to find the function first in the object and call that version which actually does another work.
But when you call this method from the Object.prototype, which is the correct version of the method, and pass the context to it, it will work correctly, because it will call the Object.prototypes method with name hasOwnProperty and just pass this object as the context of the method. So from here is the warning that you must use this methods from the prototype.
Actually you can also change the Object.prototype version of the method, but there is a rule, Not change the prototypes of the built in objects.
const object = {
hasOwnProperty: function() {
return true;
}
};
console.log(object.hasOwnProperty('name'));
console.log(Object.prototype.hasOwnProperty.call(object, 'name'));
The first log says that there is a property name in the object, but it isn't. This may cause a logic error. The second one uses the correct version and gives a correct result.

two ways of creating object in javascript

I'm creating javascript object by doing something like:
function field(name,label){
this.name = name
this.label= label;
}
var a = new field("market","Mkt").
Then I assign a to another object.
object.newField = a;
The second way of doing it is to create a new property directly
object.2ndNewField = {
name: "market2",
label:"Mkt2"
}
I try to read the objects in other functions. They behave differently, however, when i stringify the object, it looks ok. What's the difference between the two properties i created?
btw is there any difference of the following object?
object.2ndNewField = {
"name": "market2",
"label":"Mkt2
}
The difference is that in the first case, the created object inherits from field.prototype then Object.prototype (i.e. its internal [[Prototype]] is field.prototype, whose internal [[Prototype]] is Object.prototype), where as in the second case it inherits only from Object.prototype.
Another way to look at it is:
object.newField instanceof field; // true
object.newField instanceof Object; // true
object.newField2 instanceof field; // false
object.newField2 instanceof Object; // true
or the inheritance chains are:
object.newField -> field.prototype -> Object.prototype -> null
object.newField2 -> Object.prototype -> null
where '->' means "inherits from".
For the First option...Stay away from using "new". You can badly effect your global namespace if "new" is used wrong, or omitted when it should be used. Plus you have to be careful with the use of "this" in some places within your code, as it could be bound to something that you don't think it is, or even to your global data.
In your 2nd option you gave, you can safely use it for objects that are only used as a collection of data/methods (i.e. not "class-like" behavior) . If you want something that you can create multiple instances of with private and public variables/methods and can be inherited from, then you should use a function that returns an object.
I did a pretty big write up and example here of how to safely create base objects and use inheritance. If you follow the link, you will see why I didn't retype it all on this post ;).
Hope this helps...

Is Function really an Object

I am a self taught web developer and am still trying to come to grips with some JavaScript fundamentals. Below are some quotes extracted from Douglas Crockford's Good Parts.
"Functions in JavaScript are Objects"
"In JavaScript, arrays are objects, functions are objects, regular expressions are objects, and, of course, objects are objects"
"Every object is linked to a prototype object from which it can inherit properties" (namely constructor, toString, ...)
If Function is an Object then why
console.log(typeof Function); // function
is its type a function and not object
console.log(Object.constructor); // Function()
is it the constructor of its 'parent'
console.log(Function.constructor); // Function()
puzzled so the constructor is in-fact a function?
console.log(typeof Function.prototype); // Function
is the type of its prototype a function and not an object? i thought it inherited from Object
Answers to these questions will greatly assist my understanding on JavaScript.
If Function is an Object then why is its type a function and not object?
Because the typeof operator is defined like that, probably for usability:
Object (native and does not implement [[Call]]) returns "object"
Object (native or host and does implement [[Call]]) returns "function"
Object (host and does not implement [[Call]])
returns an Implementation-defined value that may not be "undefined", "boolean", "number", or "string".
[[Call]] is an internal property of an object that identifies the object as a function (callable). A non-native object is an object provided by the host (e.g. browser), such as a DOM object or an instance of ActiveXObject.
puzzled so the constructor is in-fact a function?
Why wouldn't it be? Constructors are functions. Instances can only be constructed using functions. Object.constructor is a function, but it's also an object. See the following:
console.log((function () { }) instanceof Object);
//-> true
Also, from the ECMAScript speficiation:
Every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype (15.3.4), as the value of its [[Prototype]] internal property.
Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (15.2.4), as the value of its [[Prototype]] internal property, except the Object prototype object itself.
And also, to answer your final puzzlement:
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
When we say, "a function is an object", we don't mean "is" as in "instead of", we mean it in the same sense as "a cat is an animal". If someone asked you what kind of pet you had, you wouldn't answer "an animal". typeof would be useless if it always responded object.
A function is an object, but that's not an interesting thing for typeof to return, since it's a static quality of the language itself, not something that needs to be reported at runtime.
The typeof operator would be quite useless if it always returned "object", wouldn't it? Everything is an object, but it can be other things too. For example, a string is an object, but it is also a string :) The operator returns the name of the most specific type so to speak, not the most generic one. That should explain why typeof Functionis "function".
As for the constructor property, the constructor is a function that is invoked by the operator new when an object is created. It is always a function, regardless of whether the object itself is Object, Functionor something else.
The console.log(typeof Function); shows that the object is of type Function and not object.
To give you an example:
function squareValue(var x) {
return x * x;
}
can be loosely translated as
var squareValue = new Function("x", "return x*x");
and thus, doing
var valueSquared = squareValue(x);
in any of these 2 examples, will produce the same results...
Hence why every function in Javascript is a Function object.
The .constructor, .prototype, .toString on javascript Object/Function are all functions in their respective objects hence why you have the output as "function".
This is based according to the ECMA-262 3rd Edition -December 1999
Hope this helps.
reference Is every JavaScript Object a function?
javascript:alert([ window.navigator.userAgent, Object, Function ].join("\n\n") )
displays
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423
Ubuntu/10.04 (lucid) Firefox/3.6.3
function Object() {
[native code]
}
function Function() {
[native code]
}
also
javascript:alert([ new Object, new Function ].join("\n\n") )
displays
[object Object]
function anonymous() { }
and
javascript:alert([ new new Function ].join("\n\n") )
displays
[object Object]

Categories

Resources