Introduce MDN developer.mozilla.org/zh-CN/docs/…

scenario

When pressing the add/subtract key on the keyboard, adjust the roaming speed, while a pop-up reminder.

Because the roaming operator is encapsulated as an object, the external caller is notified when the speed changes and acts accordingly

Preliminary code ideas:

As is shown in

  • 1. Bind the speed change callback function
  • 2. Business executive cameraWalkOperator. ChangeSpeed (value)
  • 3. When the speed changes, the bound operation steps are performed, and a pop-up window is displayed

To optimize the

The above code implements the requirements scenario, but the code is not very friendly and easy to maintain. Try the following abstraction

  • 1. Create a Listeners object where each property represents a listener type.
  • 2. The Type attribute of the Listeners object is an array of listener events.
  • Step 3. The 122 has been put to monitor events binding ok, now, was triggered. Write a trigger function, pass in the event type, look for the event to listen on and execute it.

Although the above code looks more complex, in fact, it is not complicated to understand, is the most native object and array combination of use.

Imagine a scenario where there are three different types of events to listen for and trigger different operations. If you use the original code idea, you have three copies of the same code, which is scattered, redundant, and highly coupled. Now we wrap it in an object. The different listener types represent the properties on the object, and the values of the properties on the object are stored in an array to hold the listener events. So all the listeners are on one object, very centralized, no redundancy, decoupled from the outside world, equivalent to a module.

To make this event listener available elsewhere, wrap it as a constructor.

EventDispatcher constructor

/ * * *@author [Wu-Qin-Hao]
 * @email [1539849378@qq.com]
 * @create date 2020-08-03 10:55:00
 * @modify date 2020-08-03 10:55:00
 * @desc [Custom event listener-Observer mode] */
function EventDispatcher() {}

Object.assign( EventDispatcher.prototype, {
	// Add event listener
 	// @type specifies the type of the search
 	// the @listener function is used to listen for execution
	addEventListener: function ( type, listener ) {
		// Initialize _listeners to {}
		if ( this._listeners === undefined ) this._listeners = {};
		// Retrieve the _listeners content
		var listeners = this._listeners;
		// If the _listeners object has no data with the type attribute initialized to []
		if ( listeners[ type ] === undefined ) {
        		listeners[ type ] = [];
		}
		// Push the listener function into the _Listeners array if there is no listener in the _Listeners array
		if ( listeners[ type ].indexOf( listener ) === - 1) { listeners[ type ].push( listener ); }},// Check whether the event is listening
 	// @type specifies the type of the search
 	// the @listener function is used to listen for execution
	hasEventListener: function ( type, listener ) {
		// Exit directly if _listeners are not defined
		if ( this._listeners === undefined ) return false;
		// Retrieve the _listeners content
		var listeners = this._listeners;
		// Find the type attribute on the _listeners object, return false directly, and continue to look for the listener function in the attribute array, return true, otherwise return false
		returnlisteners[ type ] ! = =undefined&& listeners[ type ].indexOf( listener ) ! = = -1;
	},
	// Delete event listener
	// @type specifies the type of the search
 	// the @listener function is used to listen for execution
	removeEventListener: function ( type, listener ) {
		// Exit directly if _listeners are not defined
		if ( this._listeners === undefined ) return;
		// Retrieve the _listeners content
		var listeners = this._listeners;
		// The contents of the Type attribute on the _Listeners object
		var listenerArray = listeners[ type ];
		// If there is a value
		if( listenerArray ! = =undefined ) {
        	// Check whether the listener function exists
			var index = listenerArray.indexOf( listener );
			// Delete it from the array if it exists
			if( index ! = = -1 ) {
				listenerArray.splice( index, 1); }}},// Trigger the listening function
	dispatchEvent: function ( event ) {
		// Exit directly if _listeners are not defined
		if ( this._listeners === undefined ) return;
		// Retrieve the _listeners content
		var listeners = this._listeners;
		// The contents of the Type attribute on the _Listeners object
		var listenerArray = listeners[ event.type ];
		// If there is a value
		if( listenerArray ! = =undefined ) {
			// Add the target attribute to the event object and pass the this object to the target, which may be used later by external callers
			event.target = this;
			// The slice method does not modify the array, but returns a new array
			var array = listenerArray.slice( 0 );
			// Iterate over all event listeners of type event.type
			for ( var i = 0, l = array.length; i < l; i ++ ) {
				// Call the listener event
				array[ i ].call( this, event ); }}}});export { EventDispatcher };
Copy the code

For constructors, prototype chains. See my article juejin.cn/post/684490…