Object.prototype.hasOwnProperty ()
In terms of an interview with Javascript, I think you just need to fully understand what obj.hasOwnProperty() does at the Javascript level, and not how it is implemented inside V8.
To do this, you must fully understand this little snippet:
function MyConstructor() { this.methodB = function() {} } MyConstructor.prototype = { methodA: function() {} }; var o = new MyConstructor(); log(o.hasOwnProperty("methodA"));
This is because .hasOwnProperty() only looks at the object itself and not at the prototype chain. Thus, properties that are only in the prototype chain or do not exist at all will return false , and properties that are directly on the object will return true .
Array.prototype.map ()
A polyfill in Javascript for Array.prototype.map() is here in MDN , which will show you exactly how it works. Of course, you can do the same type of search that I did above in the Github repository to find the .map() implementation if you want.
Array.prototype.map() pretty simple. Iterate over the array by calling a function for each element of the array. Each return value of this function will be used to build a new array that will be returned from the .map() call. Thus, conceptually, it was used to โmapโ one array to another, calling some conversion function for each element of the original array.
In the simplest embodiment, you add 1 to each element of the array:
var origArray = [1,2,3]; var newArray = origArray.map(function(item, index, array) { return item + 1; }); console.log(newArray);
Actual V8 source code:
If you really want to see how it is implemented inside V8, here are the code snippets and links to the corresponding actual code files. As you can see, most of them are in C ++ and in order to understand this you need to understand how objects are structured in memory and what C ++ methods they have inside V8. This is a very V8-specific, not general Javascript knowledge.
I also included links to the corresponding source files, so if you want to see a different context in these files, you can click on the links to see this.
In v8.h :
V8_DEPRECATED("Use maybe version", bool HasOwnProperty(Local<String> key)); V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context, Local<Name> key);
In api.cc :
Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context, Local<Name> key) { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()", bool); auto self = Utils::OpenHandle(this); auto key_val = Utils::OpenHandle(*key); auto result = i::JSReceiver::HasOwnProperty(self, key_val); has_pending_exception = result.IsNothing(); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); return result; } bool v8::Object::HasOwnProperty(Local<String> key) { auto context = ContextFromHeapObject(Utils::OpenHandle(this)); return HasOwnProperty(context, key).FromMaybe(false); }
In v8natives.js :
// ES6 7.3.11 function ObjectHasOwnProperty(value) { var name = TO_NAME(value); var object = TO_OBJECT(this); return %HasOwnProperty(object, name); }
In objects-inl.h :
Maybe<bool> JSReceiver::HasOwnProperty(Handle<JSReceiver> object, Handle<Name> name) { if (object->IsJSObject()) { // Shortcut LookupIterator it = LookupIterator::PropertyOrElement( object->GetIsolate(), object, name, LookupIterator::HIDDEN); return HasProperty(&it); } Maybe<PropertyAttributes> attributes = JSReceiver::GetOwnPropertyAttributes(object, name); MAYBE_RETURN(attributes, Nothing<bool>()); return Just(attributes.FromJust() != ABSENT); }
In runtime-object.cc :
static Object* HasOwnPropertyImplementation(Isolate* isolate, Handle<JSObject> object, Handle<Name> key) { Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key); if (!maybe.IsJust()) return isolate->heap()->exception(); if (maybe.FromJust()) return isolate->heap()->true_value(); // Handle hidden prototypes. If there a hidden prototype above this thing // then we have to check it for properties, because they are supposed to // look like they are on this object. if (object->map()->has_hidden_prototype()) { PrototypeIterator iter(isolate, object); DCHECK(!iter.IsAtEnd()); // TODO(verwaest): The recursion is not necessary for keys that are array // indices. Removing this. // Casting to JSObject is fine because JSProxies are never used as // hidden prototypes. return HasOwnPropertyImplementation( isolate, PrototypeIterator::GetCurrent<JSObject>(iter), key); } RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); return isolate->heap()->false_value(); } RUNTIME_FUNCTION(Runtime_HasOwnProperty) { HandleScope scope(isolate); DCHECK(args.length() == 2); CONVERT_ARG_HANDLE_CHECKED(Object, object, 0) CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); uint32_t index; const bool key_is_array_index = key->AsArrayIndex(&index); // Only JS objects can have properties. if (object->IsJSObject()) { Handle<JSObject> js_obj = Handle<JSObject>::cast(object); // Fast case: either the key is a real named property or it is not // an array index and there are no interceptors or hidden // prototypes. // TODO(jkummerow): Make JSReceiver::HasOwnProperty fast enough to // handle all cases directly (without this custom fast path). Maybe<bool> maybe = Nothing<bool>(); if (key_is_array_index) { LookupIterator it(js_obj->GetIsolate(), js_obj, index, LookupIterator::HIDDEN); maybe = JSReceiver::HasProperty(&it); } else { maybe = JSObject::HasRealNamedProperty(js_obj, key); } if (!maybe.IsJust()) return isolate->heap()->exception(); DCHECK(!isolate->has_pending_exception()); if (maybe.FromJust()) { return isolate->heap()->true_value(); } Map* map = js_obj->map(); if (!key_is_array_index && !map->has_named_interceptor() && !map->has_hidden_prototype()) { return isolate->heap()->false_value(); } // Slow case. return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj), Handle<Name>(key)); } else if (object->IsString() && key_is_array_index) { // Well, there is one exception: Handle [] on strings. Handle<String> string = Handle<String>::cast(object); if (index < static_cast<uint32_t>(string->length())) { return isolate->heap()->true_value(); } } else if (object->IsJSProxy()) { Maybe<bool> result = JSReceiver::HasOwnProperty(Handle<JSProxy>::cast(object), key); if (!result.IsJust()) return isolate->heap()->exception(); return isolate->heap()->ToBoolean(result.FromJust()); } return isolate->heap()->false_value(); }
This is the node.js Github repository . If you know what to look for and have enough patience to go through all the searches, you can find everything you need. The unfortunate thing about searching on Github is that I did not find a way to remove all the test subdirectories from the search so that you get 95% of the search queries in the test code, and not in the actual implementation code. But, with sufficient perseverance, you may end up finding what you need.