Index: src/wp-includes/nav-menu-template.php
===================================================================
--- src/wp-includes/nav-menu-template.php	(revision 37687)
+++ src/wp-includes/nav-menu-template.php	(working copy)
@@ -96,7 +96,7 @@
 		$menu = wp_get_nav_menu_object( $locations[ $args->theme_location ] );
 
 	// get the first menu that has items if we still can't find a menu
-	if ( ! $menu && !$args->theme_location ) {
+	if ( ! $menu && !$args->theme_location && empty( $menu_items ) ) {
 		$menus = wp_get_nav_menus();
 		foreach ( $menus as $menu_maybe ) {
 			if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id, array( 'update_post_term_cache' => false ) ) ) {
@@ -111,7 +111,7 @@
 	}
 
 	// If the menu exists, get its items.
-	if ( $menu && ! is_wp_error($menu) && !isset($menu_items) )
+	if ( $menu && ! is_wp_error($menu) && empty($menu_items) )
 		$menu_items = wp_get_nav_menu_items( $menu->term_id, array( 'update_post_term_cache' => false ) );
 
 	/*
Index: src/wp-includes/nav-menu.php
===================================================================
--- src/wp-includes/nav-menu.php	(revision 37687)
+++ src/wp-includes/nav-menu.php	(working copy)
@@ -621,6 +621,22 @@
 		return false;
 	}
 
+
+	/**
+	 * Filters whether to short-circuit the navigation menu items being returned.
+	 *
+	 * @since 4.6.0
+	 *
+	 * @param array|null  $items An array of menu item post objects to short-circuit with. Default null.
+	 * @param object $menu  The menu object.
+	 * @param array  $args  An array of arguments used to retrieve menu item objects.
+	 */
+	$items = apply_filters( 'pre_wp_get_nav_menu_items', null, $menu, $args );
+
+	if ( null !== $items ) {
+		return $items;
+	}
+
 	static $fetched = array();
 
 	$items = get_objects_in_term( $menu->term_id, 'nav_menu' );
