When bar.constructor === Object is true? - javascript

On totpal
Below question is present.
What is a potential pitfall with using typeof bar === "object" to
determine if bar is an object? How can this pitfall be avoided?
Among its answers below statement is present
However, there’s one other alternative that returns false for nulls,
arrays, and functions, but true for objects:
console.log((bar !== null) && (bar.constructor === Object));
But when I try my code
var myObj =
{
name: "blah"
}
var bar =3;
console.log(typeof bar.constructor)
console.log(typeof myObj.constructor)
it gives output as function for both console.log
My question is what type of objects will have (bar.constructor === Object) as true?

"My question is what type of objects will have (bar.constructor === Object) as true?"
Generally, objects that inherit directly from Object.prototype instead of some intermediate constructor's .prototype or null.
Note that objects that do inherit directly from Object.prototype but shadow the .constructor property with its own value that doesn't point to Object will of course result in a false result of an equality comparison.
var o = {};
console.log(o.constructor === Object); // true
o.constructor = "foo";
console.log(o.constructor === Object); // false
Also, objects that do not inherit directly from Object.prototype, but rather from some other constructor that has a .prototype without a .constructor property will give a true result.
function Ctor() {}
var o = new Ctor();
console.log(o.constructor === Object); // false
delete Ctor.prototype.constructor;
console.log(o.constructor === Object); // true

Related

Why does strings are not instance of String in javascript? [duplicate]

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

Why is the `prototype` field of the built-in Object function treated differently in JavaScript?

Conceptually, I thought if an object obj is an instance of a "class/constructor" Constructor, then Object.getPrototypeOf(obj) === Constructor.prototype.
This pattern works for almost all "types", including most built-in functions:
Object.getPrototypeOf(Boolean.prototype) === Object.prototype
true
Object.getPrototypeOf(Function.prototype) === Object.prototype
true
Object.getPrototypeOf(String.prototype) === Object.prototype
true
But this does not seem to apply to the built-in function Object.
Object.getPrototypeOf(Object.prototype) === Object.prototype
false // <----------------- Why?
Well, Object.prototype intuitively is an object too. But the above pattern does not apply. Did I miss anything?
I think result of Object.getPrototypeOf(Object.prototype) that saying Object.prototype doesn't have a prototype is a well explanation.
const protoOf_true = Object.getPrototypeOf(true);
console.log(Boolean.prototype === protoOf_true);
const protoOf_Boolean = Object.getPrototypeOf(protoOf_true);
console.log(Object.prototype === protoOf_Boolean);
const protoOf_Object = Object.getPrototypeOf(protoOf_Boolean);
console.log(null === protoOf_Object);

JavaScript String Literal Constructor [duplicate]

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

constructor vs typeof to detect type in JavaScript

In this question I did not see suggestions to use constructor.
So instead of typeof callback == "function"
I would use callback && (callback.constructor==Function).
To me it seems obvious that comparison to memory pointers is always better than comparison to strings in terms of both runtime performance and coding safety.
Why not use constructor to detect all types and forget about ugly typeof?
It works for all primitive types, functions and arrays:
undefined === undefined
null === null
[1,2,3].constructor == Array
(1).constructor == Number
(true).constructor == Boolean
(()=>null).constructor == Function
'abc'.constructor == String
(new Date()).constructor == Date
else it's an object, where instanceof helps to detect it's parents if needed.
If string interning can be relied upon then runtime performance advantage goes away. But safe coding advantage still stays.
instanceof is better because it works with inherited constructors. .constructor is a mutable property on an object, so it's not a good thing to check because one can simply change it. You can't change the instanceof something.
const x = new Date();
console.log("Date Constructor", x.constructor);
x.constructor = "herpderpderp";
console.log("Date Constructor", x.constructor);
You can also define your own functions for both tests that also work on primitives by using getPrototypeOf and isPrototypeOf. E.G.:
function typeOf(obj) {
return Object.getPrototypeOf(obj).constructor;
}
typeOf(2) === Number // true
typeOf("cats") === String // true
class Foo {}
typeOf(new Foo()) === Foo // true
class Bar extends Foo {}
typeOf(new Bar()) === Bar // true
typeOf(new Bar()) === Foo // false
var b = new Number(3)
if (typeOf(b) === Number) {
console.log(b.valueOf() + 5)
}
and
function instanceOf(obj, type) {
var objType = typeOf(obj)
return (
// Allow native instanceof in case of Symbol.hasInstance
obj instanceof type ||
// Handle case where is of type type
typeOf(obj) === type ||
// Handle general case
type.isPrototypeOf(objType) ||
// Handle special case where type.prototype acts as a
// prototype of the object but its type isn't in the
// prototype chain of the obj's type
// OPTIONALLY remove this case if you don't want
// primitives to be considered instances of Object
type.prototype.isPrototypeOf(objType.prototype)
);
}
instanceOf(3, Number) // true
instanceOf(new Number("2"), Number) // true
instanceOf(2, Number) // true, OPTIONAL with the last condition
// but is probably preferable as 2 does
// indeed get all methods of Objects
class Hat {}
instanceOf(new Hat(), Hat) // true
class Fedora extends Hat {}
instanceOf(new Fedora(), Fedora) // true
instanceOf(new Fedora(), Hat) // true
instanceOf(new Fedora(), Object) // true

What does Object(obj) === obj do?

different from obj != null;
I know that obj != null will detect anything that is allowed to have properties on it as null and undefined are the only two values which can not have properties.
How does this differ from
Object(obj) === obj;
Object(obj) === obj tests whether obj is an object or a primitive, failing also for strings, etc.
console.log(Object('foo') === 'foo'); // false
console.log(Object(true) === true); // false
console.log(Object(null) === null); // false
var obj = {};
console.log(Object(obj) === obj); // true
It's useful for determining if the value can be given and remember an assigned property.
While null and undefined outright error when attempting to use properties, which is why obj != null is still useful, no primitive values are able to hold onto properties.
var pri = 'foo';
pri.foo = 'bar'; // no error, but still...
console.log(pri.foo); // undefined
var box = Object(pri);
box.foo = 'bar';
console.log(box.foo); // 'bar'
Reference:
When obj is null or undefined, Object(obj) returns a new Object():
1) If value is null, undefined or not supplied, create and return a new Object object exactly as if the standard built-in Object constructor had been called with the same arguments (15.2.2.1).
And, primitive booleans, strings, and numbers are boxed into their object types via ToObject(), which are not equal to their primitive equivalents:
2) Return ToObject(value).
console.log(typeof 'foo' === 'string'); // true
console.log(typeof Object('foo') === 'object'); // true
console.log('foo' instanceof String); // false
console.log(Object('foo') instanceof String); // true
Identity (===. !==)
These operators behave identically to the equality operators except no type conversion is done, and the types must be the same to be considered equal.
http://www.c-point.com/javascript_tutorial/jsgrpComparison.htm
Nice Stack overflow link
Which equals operator (== vs ===) should be used in JavaScript comparisons?
Hope it helps

Categories

Resources