diff --git src/wp-admin/includes/ajax-actions.php src/wp-admin/includes/ajax-actions.php
index 34d179c..2effada 100644
--- src/wp-admin/includes/ajax-actions.php
+++ src/wp-admin/includes/ajax-actions.php
@@ -136,9 +136,9 @@ function wp_ajax_ajax_tag_search() {
 	 *
 	 * @since 4.0.0
 	 *
-	 * @param int    $characters The minimum number of characters required. Default 2.
-	 * @param object $tax        The taxonomy object.
-	 * @param string $s          The search term.
+	 * @param int         $characters The minimum number of characters required. Default 2.
+	 * @param WP_Taxonomy $tax        The taxonomy object.
+	 * @param string      $s          The search term.
 	 */
 	$term_search_min_chars = (int) apply_filters( 'term_search_min_chars', 2, $tax, $s );
 
diff --git src/wp-includes/class-wp-taxonomy.php src/wp-includes/class-wp-taxonomy.php
new file mode 100644
index 0000000..30fa9a1
--- /dev/null
+++ src/wp-includes/class-wp-taxonomy.php
@@ -0,0 +1,373 @@
+<?php
+/**
+ * Taxonomy API: WP_Taxonomy class
+ *
+ * @package    WordPress
+ * @subpackage Taxonomy
+ * @since      4.6.0
+ */
+
+/**
+ * Core class used for interacting with taxonomies.
+ *
+ * @since 4.6.0
+ */
+final class WP_Taxonomy implements ArrayAccess {
+	/**
+	 * Taxonomy key.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $name;
+
+	/**
+	 * Name of the taxonomy shown in the menu. Usually plural.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $label;
+
+	/**
+	 * An array of labels for this taxonomy.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array
+	 */
+	public $labels = array();
+
+	/**
+	 * A short descriptive summary of what the taxonomy is for.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var string
+	 */
+	public $description = '';
+
+	/**
+	 * Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $public = true;
+
+	/**
+	 * Whether the taxonomy is publicly queryable.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $publicly_queryable = true;
+
+	/**
+	 * Whether the taxonomy is hierarchical.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $hierarchical = false;
+
+	/**
+	 * Whether to generate and allow a UI for managing terms in this taxonomy in the admin.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_ui = true;
+
+	/**
+	 * Whether to show the taxonomy in the admin menu.
+	 *
+	 * If true, the taxonomy is shown as a submenu of the object type menu. If false, no menu is shown.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_menu = true;
+
+	/**
+	 * Whether the taxonomy is available for selection in navigation menus.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_nav_menus = true;
+
+	/**
+	 * Whether to list the taxonomy in the tag cloud widget controls.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_tagcloud = true;
+
+	/**
+	 * Whether to show the taxonomy in the quick/bulk edit panel.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_in_quick_edit = true;
+
+	/**
+	 * Whether to display a column for the taxonomy on its post type listing screens.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool
+	 */
+	public $show_admin_column = false;
+
+	/**
+	 * The callback function for the meta box display.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var bool|callable
+	 */
+	public $meta_box_cb = null;
+
+	/**
+	 * An array of object types this taxonomy is registered for.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @var array
+	 */
+	public $object_type = null;
+
+	/**
+	 * Constructor.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @global WP $wp WP instance.
+	 *
+	 * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
+	 * @param array|string $object_type Name of the object type for the taxonomy object.
+	 * @param array|string $args        {
+	 *                                  Optional. Array or query string of arguments for registering a taxonomy.
+	 */
+	public function __construct( $taxonomy, $object_type, $args ) {
+		global $wp;
+
+		$args = wp_parse_args( $args );
+
+		/**
+		 * Filter the arguments for registering a taxonomy.
+		 *
+		 * @since 4.4.0
+		 *
+		 * @param array  $args        Array of arguments for registering a taxonomy.
+		 * @param string $taxonomy    Taxonomy key.
+		 * @param array  $object_type Array of names of object types for the taxonomy.
+		 */
+		$args = apply_filters( 'register_taxonomy_args', $args, $taxonomy, (array) $object_type );
+
+		$defaults = array(
+			'labels'                => array(),
+			'description'           => '',
+			'public'                => true,
+			'publicly_queryable'    => null,
+			'hierarchical'          => false,
+			'show_ui'               => null,
+			'show_in_menu'          => null,
+			'show_in_nav_menus'     => null,
+			'show_tagcloud'         => null,
+			'show_in_quick_edit'    => null,
+			'show_admin_column'     => false,
+			'meta_box_cb'           => null,
+			'capabilities'          => array(),
+			'rewrite'               => true,
+			'query_var'             => $taxonomy,
+			'update_count_callback' => '',
+			'_builtin'              => false,
+		);
+		$args     = array_merge( $defaults, $args );
+
+		// If not set, default to the setting for public.
+		if ( null === $args['publicly_queryable'] ) {
+			$args['publicly_queryable'] = $args['public'];
+		}
+
+		// Non-publicly queryable taxonomies should not register query vars, except in the admin.
+		if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) && ! empty( $wp ) ) {
+			if ( true === $args['query_var'] ) {
+				$args['query_var'] = $taxonomy;
+			} else {
+				$args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
+			}
+			$wp->add_query_var( $args['query_var'] );
+		} else {
+			// Force query_var to false for non-public taxonomies.
+			$args['query_var'] = false;
+		}
+
+		if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
+			$args['rewrite'] = wp_parse_args( $args['rewrite'], array(
+				'with_front'   => true,
+				'hierarchical' => false,
+				'ep_mask'      => EP_NONE,
+			) );
+
+			if ( empty( $args['rewrite']['slug'] ) ) {
+				$args['rewrite']['slug'] = sanitize_title_with_dashes( $taxonomy );
+			}
+
+			if ( $args['hierarchical'] && $args['rewrite']['hierarchical'] ) {
+				$tag = '(.+?)';
+			} else {
+				$tag = '([^/]+)';
+			}
+
+			add_rewrite_tag( "%$taxonomy%", $tag, $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=" );
+			add_permastruct( $taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%", $args['rewrite'] );
+		}
+
+		// If not set, default to the setting for public.
+		if ( null === $args['show_ui'] ) {
+			$args['show_ui'] = $args['public'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_in_menu'] || ! $args['show_ui'] ) {
+			$args['show_in_menu'] = $args['show_ui'];
+		}
+
+		// If not set, default to the setting for public.
+		if ( null === $args['show_in_nav_menus'] ) {
+			$args['show_in_nav_menus'] = $args['public'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_tagcloud'] ) {
+			$args['show_tagcloud'] = $args['show_ui'];
+		}
+
+		// If not set, default to the setting for show_ui.
+		if ( null === $args['show_in_quick_edit'] ) {
+			$args['show_in_quick_edit'] = $args['show_ui'];
+		}
+
+		$default_caps = array(
+			'manage_terms' => 'manage_categories',
+			'edit_terms'   => 'manage_categories',
+			'delete_terms' => 'manage_categories',
+			'assign_terms' => 'edit_posts',
+		);
+		$args['cap']  = (object) array_merge( $default_caps, $args['capabilities'] );
+		unset( $args['capabilities'] );
+
+		$args['name']        = $taxonomy;
+		$args['object_type'] = array_unique( (array) $object_type );
+
+		$args['labels'] = get_taxonomy_labels( (object) $args );
+		$args['label']  = $args['labels']->name;
+
+		// If not set, use the default meta box
+		if ( null === $args['meta_box_cb'] ) {
+			if ( $args['hierarchical'] ) {
+				$args['meta_box_cb'] = 'post_categories_meta_box';
+			} else {
+				$args['meta_box_cb'] = 'post_tags_meta_box';
+			}
+		}
+
+		foreach ( $args as $key => $value ) {
+			$this->$key = $value;
+		}
+	}
+
+	/**
+	 * Retrieves the taxonomy object of `$taxonomy`.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 * @static
+	 *
+	 * @global array $wp_taxonomies The registered taxonomies.
+	 *
+	 * @param string $taxonomy Name of taxonomy object to return.
+	 * @return WP_Taxonomy|false The Taxonomy object or false if taxonomy does not exist.
+	 */
+	public static function get_instance( $taxonomy ) {
+		global $wp_taxonomies;
+
+		if ( ! taxonomy_exists( $taxonomy ) )
+			return false;
+
+		return $wp_taxonomies[$taxonomy];
+	}
+
+	/**
+	 * Method to implement ArrayAccess for taxonomy arguments.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @param mixed $offset
+	 * @param mixed $value
+	 */
+	public function offsetSet( $offset, $value ) {
+		if ( $this->offsetExists( $offset ) ) {
+			$this->$offset = $value;
+		}
+	}
+
+	/**
+	 * Method to implement ArrayAccess for taxonomy arguments.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @param mixed $offset
+	 */
+	public function offsetUnset( $offset ) {
+		if ( $this->offsetExists( $offset ) ) {
+			unset( $this->$offset );
+		}
+	}
+
+	/**
+	 * Method to implement ArrayAccess for taxonomy arguments.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @param mixed $offset
+	 * @return bool
+	 */
+	public function offsetExists( $offset ) {
+		return property_exists( $this, $offset );
+	}
+
+	/**
+	 * Method to implement ArrayAccess for taxonomy arguments.
+	 *
+	 * @since 4.6.0
+	 * @access public
+	 *
+	 * @param mixed $offset
+	 * @return mixed
+	 */
+	public function offsetGet( $offset ) {
+		if ( $this->offsetExists( $offset ) ) {
+			return $this->$offset;
+		}
+	}
+}
diff --git src/wp-includes/class-wp-xmlrpc-server.php src/wp-includes/class-wp-xmlrpc-server.php
index c331591..7058f51 100644
--- src/wp-includes/class-wp-xmlrpc-server.php
+++ src/wp-includes/class-wp-xmlrpc-server.php
@@ -695,9 +695,9 @@ class wp_xmlrpc_server extends IXR_Server {
 		 *
 		 * @since 3.4.0
 		 *
-		 * @param array  $_taxonomy An array of taxonomy data.
-		 * @param object $taxonomy  Taxonomy object.
-		 * @param array  $fields    The subset of taxonomy fields to return.
+		 * @param array       $_taxonomy An array of taxonomy data.
+		 * @param WP_Taxonomy $taxonomy  Taxonomy object.
+		 * @param array       $fields    The subset of taxonomy fields to return.
 		 */
 		return apply_filters( 'xmlrpc_prepare_taxonomy', $_taxonomy, $taxonomy, $fields );
 	}
diff --git src/wp-includes/taxonomy.php src/wp-includes/taxonomy.php
index 8fad3d9..93547fb 100644
--- src/wp-includes/taxonomy.php
+++ src/wp-includes/taxonomy.php
@@ -162,9 +162,9 @@ function get_taxonomies( $args = array(), $output = 'names', $operator = 'and' )
  * Example:
  *
  *     $taxonomies = get_object_taxonomies( 'post' );
- * 
+ *
  * This results in:
- * 
+ *
  *     Array( 'category', 'post_tag' )
  *
  * @since 2.3.0
@@ -208,18 +208,11 @@ function get_object_taxonomies( $object, $output = 'names' ) {
  *
  * @since 2.3.0
  *
- * @global array $wp_taxonomies The registered taxonomies.
- *
  * @param string $taxonomy Name of taxonomy object to return.
- * @return object|false The Taxonomy Object or false if $taxonomy doesn't exist.
+ * @return WP_Taxonomy|false The Taxonomy object or false if taxonomy does not exist.
  */
 function get_taxonomy( $taxonomy ) {
-	global $wp_taxonomies;
-
-	if ( ! taxonomy_exists( $taxonomy ) )
-		return false;
-
-	return $wp_taxonomies[$taxonomy];
+	return WP_Taxonomy::get_instance( $taxonomy );
 }
 
 /**
@@ -276,9 +269,9 @@ function is_taxonomy_hierarchical($taxonomy) {
  * @since 4.4.0 The `show_ui` argument is now enforced on the term editing screen.
  * @since 4.4.0 The `public` argument now controls whether the taxonomy can be queried on the front end.
  * @since 4.5.0 Introduced `publicly_queryable` argument.
+ * @since 4.6.0 The function now returns the registered taxonomy object on success.
  *
  * @global array $wp_taxonomies Registered taxonomies.
- * @global WP    $wp            WP instance.
  *
  * @param string       $taxonomy    Taxonomy key, must not exceed 32 characters.
  * @param array|string $object_type Name of the object type for the taxonomy object.
@@ -346,136 +339,25 @@ function is_taxonomy_hierarchical($taxonomy) {
  *     @type bool          $_builtin              This taxonomy is a "built-in" taxonomy. INTERNAL USE ONLY!
  *                                                Default false.
  * }
- * @return WP_Error|void WP_Error, if errors.
+ * @return WP_Taxonomy|WP_Error The registered taxonomy object, or an error object.
  */
 function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
-	global $wp_taxonomies, $wp;
+	global $wp_taxonomies;
 
-	if ( ! is_array( $wp_taxonomies ) )
+	if ( ! is_array( $wp_taxonomies ) ) {
 		$wp_taxonomies = array();
-
-	$args = wp_parse_args( $args );
-
-	/**
-	 * Filter the arguments for registering a taxonomy.
-	 *
-	 * @since 4.4.0
-	 *
-	 * @param array  $args        Array of arguments for registering a taxonomy.
-	 * @param string $taxonomy    Taxonomy key.
-	 * @param array  $object_type Array of names of object types for the taxonomy.
-	 */
-	$args = apply_filters( 'register_taxonomy_args', $args, $taxonomy, (array) $object_type );
-
-	$defaults = array(
-		'labels'                => array(),
-		'description'           => '',
-		'public'                => true,
-		'publicly_queryable'    => null,
-		'hierarchical'          => false,
-		'show_ui'               => null,
-		'show_in_menu'          => null,
-		'show_in_nav_menus'     => null,
-		'show_tagcloud'         => null,
-		'show_in_quick_edit'	=> null,
-		'show_admin_column'     => false,
-		'meta_box_cb'           => null,
-		'capabilities'          => array(),
-		'rewrite'               => true,
-		'query_var'             => $taxonomy,
-		'update_count_callback' => '',
-		'_builtin'              => false,
-	);
-	$args = array_merge( $defaults, $args );
+	}
 
 	if ( empty( $taxonomy ) || strlen( $taxonomy ) > 32 ) {
 		_doing_it_wrong( __FUNCTION__, __( 'Taxonomy names must be between 1 and 32 characters in length.' ), '4.2' );
 		return new WP_Error( 'taxonomy_length_invalid', __( 'Taxonomy names must be between 1 and 32 characters in length.' ) );
 	}
 
-	// If not set, default to the setting for public.
-	if ( null === $args['publicly_queryable'] ) {
-		$args['publicly_queryable'] = $args['public'];
-	}
+	$taxonomy_object = new WP_Taxonomy( $taxonomy, $object_type, $args );
 
-	// Non-publicly queryable taxonomies should not register query vars, except in the admin.
-	if ( false !== $args['query_var'] && ( is_admin() || false !== $args['publicly_queryable'] ) && ! empty( $wp ) ) {
-		if ( true === $args['query_var'] )
-			$args['query_var'] = $taxonomy;
-		else
-			$args['query_var'] = sanitize_title_with_dashes( $args['query_var'] );
-		$wp->add_query_var( $args['query_var'] );
-	} else {
-		// Force query_var to false for non-public taxonomies.
-		$args['query_var'] = false;
-	}
-
-	if ( false !== $args['rewrite'] && ( is_admin() || '' != get_option( 'permalink_structure' ) ) ) {
-		$args['rewrite'] = wp_parse_args( $args['rewrite'], array(
-			'with_front' => true,
-			'hierarchical' => false,
-			'ep_mask' => EP_NONE,
-		) );
-
-		if ( empty( $args['rewrite']['slug'] ) )
-			$args['rewrite']['slug'] = sanitize_title_with_dashes( $taxonomy );
-
-		if ( $args['hierarchical'] && $args['rewrite']['hierarchical'] )
-			$tag = '(.+?)';
-		else
-			$tag = '([^/]+)';
-
-		add_rewrite_tag( "%$taxonomy%", $tag, $args['query_var'] ? "{$args['query_var']}=" : "taxonomy=$taxonomy&term=" );
-		add_permastruct( $taxonomy, "{$args['rewrite']['slug']}/%$taxonomy%", $args['rewrite'] );
-	}
-
-	// If not set, default to the setting for public.
-	if ( null === $args['show_ui'] )
-		$args['show_ui'] = $args['public'];
-
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_in_menu' ] || ! $args['show_ui'] )
-		$args['show_in_menu' ] = $args['show_ui'];
-
-	// If not set, default to the setting for public.
-	if ( null === $args['show_in_nav_menus'] )
-		$args['show_in_nav_menus'] = $args['public'];
-
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_tagcloud'] )
-		$args['show_tagcloud'] = $args['show_ui'];
+	$wp_taxonomies[ $taxonomy ] = $taxonomy_object;
 
-	// If not set, default to the setting for show_ui.
-	if ( null === $args['show_in_quick_edit'] ) {
-		$args['show_in_quick_edit'] = $args['show_ui'];
-	}
-
-	$default_caps = array(
-		'manage_terms' => 'manage_categories',
-		'edit_terms'   => 'manage_categories',
-		'delete_terms' => 'manage_categories',
-		'assign_terms' => 'edit_posts',
-	);
-	$args['cap'] = (object) array_merge( $default_caps, $args['capabilities'] );
-	unset( $args['capabilities'] );
-
-	$args['name'] = $taxonomy;
-	$args['object_type'] = array_unique( (array) $object_type );
-
-	$args['labels'] = get_taxonomy_labels( (object) $args );
-	$args['label'] = $args['labels']->name;
-
-	// If not set, use the default meta box
-	if ( null === $args['meta_box_cb'] ) {
-		if ( $args['hierarchical'] )
-			$args['meta_box_cb'] = 'post_categories_meta_box';
-		else
-			$args['meta_box_cb'] = 'post_tags_meta_box';
-	}
-
-	$wp_taxonomies[ $taxonomy ] = (object) $args;
-
-	// register callback handling for metabox
+	// Register callback handling for metabox.
  	add_filter( 'wp_ajax_add-' . $taxonomy, '_wp_ajax_add_hierarchical_term' );
 
 	/**
@@ -483,11 +365,13 @@ function register_taxonomy( $taxonomy, $object_type, $args = array() ) {
 	 *
 	 * @since 3.3.0
 	 *
-	 * @param string       $taxonomy    Taxonomy slug.
-	 * @param array|string $object_type Object type or array of object types.
-	 * @param array        $args        Array of taxonomy registration arguments.
+	 * @param string       $taxonomy        Taxonomy slug.
+	 * @param array|string $object_type     Object type or array of object types.
+	 * @param WP_Taxonomy  $taxonomy_object The registered taxonomy object.
 	 */
-	do_action( 'registered_taxonomy', $taxonomy, $object_type, $args );
+	do_action( 'registered_taxonomy', $taxonomy, $object_type, $taxonomy_object );
+
+	return $taxonomy_object;
 }
 
 /**
@@ -579,7 +463,7 @@ function unregister_taxonomy( $taxonomy ) {
  * @since 4.3.0 Added the `no_terms` label.
  * @since 4.4.0 Added the `items_list_navigation` and `items_list` labels.
  *
- * @param object $tax Taxonomy object.
+ * @param object|WP_Taxonomy $tax Custom-something object or WP_Taxonomy object.
  * @return object object with all the labels as member variables.
  */
 function get_taxonomy_labels( $tax ) {
diff --git src/wp-settings.php src/wp-settings.php
index a4bb370..d7ecfc3 100644
--- src/wp-settings.php
+++ src/wp-settings.php
@@ -166,6 +166,7 @@ require( ABSPATH . WPINC . '/cron.php' );
 require( ABSPATH . WPINC . '/deprecated.php' );
 require( ABSPATH . WPINC . '/script-loader.php' );
 require( ABSPATH . WPINC . '/taxonomy.php' );
+require( ABSPATH . WPINC . '/class-wp-taxonomy.php' );
 require( ABSPATH . WPINC . '/class-wp-term.php' );
 require( ABSPATH . WPINC . '/class-wp-tax-query.php' );
 require( ABSPATH . WPINC . '/update.php' );
diff --git tests/phpunit/tests/term/wpTaxonomy.php tests/phpunit/tests/term/wpTaxonomy.php
new file mode 100644
index 0000000..d80700a
--- /dev/null
+++ tests/phpunit/tests/term/wpTaxonomy.php
@@ -0,0 +1,27 @@
+<?php
+
+/**
+ * @group taxonomy
+ */
+class Tests_WP_Taxonomy extends WP_UnitTestCase {
+	public function test_get_instance_invalid_taxonomy() {
+		$this->assertFalse( WP_Taxonomy::get_instance( 'foo' ) );
+	}
+
+	public function test_get_instance_builtin_taxonomy() {
+		$taxonomy = WP_Taxonomy::get_instance( 'category' );
+		$this->assertInstanceOf( 'WP_Taxonomy', $taxonomy );
+		$this->assertEquals( 'category', $taxonomy->name );
+
+		$taxonomy = WP_Taxonomy::get_instance( 'post_tag' );
+		$this->assertInstanceOf( 'WP_Taxonomy', $taxonomy );
+		$this->assertEquals( 'post_tag', $taxonomy->name );
+	}
+
+	public function test_array_access() {
+		$taxonomy = rand_str();
+		$taxonomy_object = register_taxonomy( $taxonomy, 'post' );
+		$this->assertEquals( $taxonomy, $taxonomy_object['name'] );
+		$this->assertEquals( $taxonomy, $taxonomy_object->name );
+	}
+}
