Maybe this is a newbie question, but I cannot find or think out the explanation.
Start the Node.js console, and:
> global.hasOwnProperty === hasOwnProperty
true
Then why
> global.hasOwnProperty("x")
false
but
> hasOwnProperty("x")
TypeError: Cannot convert undefined or null to object
at hasOwnProperty (<anonymous>)
at repl:1:1
at sigintHandlersWrap (vm.js:22:35)
at sigintHandlersWrap (vm.js:96:12)
at ContextifyScript.Script.runInThisContext (vm.js:21:12)
at REPLServer.defaultEval (repl.js:313:29)
at bound (domain.js:280:14)
at REPLServer.runBound [as eval] (domain.js:293:12)
at REPLServer.<anonymous> (repl.js:513:10)
at emitOne (events.js:101:20)
?
The issue here is that
hasOwnProperty()
is a method of an object and its entire function is to operate on properties of that object. As such, it only works if, when it is called, it is given a proper object context. Normally they are written methods, expect that object context is to arrive in the value ofthis
when the method is invoked.In most cases in JavaScript (except for functions defined with the arrow syntax), the value of
this
is determined by how a method is called. The usual and most common way to invoke a method on the appropriate object is with:obj.method()
This will cause JavaScript to set
this
toobj
when it calledmethod()
.If you do something like this:
And, then you call that method with no object reference as in:
Then, the object reference in
obj
is lost and is not given to the method in any way. The JavaScript interpreter will pick a default value forthis
.In strict mode,
this
will be set toundefined
and any method that attempts to use that value, expecting it to be an object reference, will fail.In non-strict mode, a browser will set
this
to point to "some default value". In a browser, that is thewindow
object. So, if you were trying to use the method on the window object, lo and behold, it would happen to work. I consider this somewhat of an accident, not good code.IMO, the moral of the story is that any method that expects to be associated with an object should be called with an explicit object reference. Then, that removes all confusion, removes all difference between strict mode and non-strict mode and removes all difference between a browser and Node.js.
If you're trying to call
hasOwnProperty()
to test a property of the global object in node.js, then call the method with the context of theglobal
object as in:That will work everywhere and is considered good and proper Javascript code. Calling it without the proper object context causes the
this
value to be set to a default value. In node.js, that default value will not necessarily be the global object. But, in all cases, you should NEVER rely on what that default value will be. Program correctly by always specifying the desired object reference and your code will work fine everywhere.FYI, there are more ways to control what
this
is passed a function than justobj.method()
. You can read about the other ways here in this other answer. They include things such as.call()
,.apply()
, arrow functions (in ES6), etc...