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 ofthiswhen the method is invoked.In most cases in JavaScript (except for functions defined with the arrow syntax), the value of
thisis 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
thistoobjwhen 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
objis lost and is not given to the method in any way. The JavaScript interpreter will pick a default value forthis.In strict mode,
thiswill be set toundefinedand 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
thisto point to "some default value". In a browser, that is thewindowobject. 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 theglobalobject as in:That will work everywhere and is considered good and proper Javascript code. Calling it without the proper object context causes the
thisvalue 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
thisis 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...