Subrayar la interpretación del código fuente: suplementos al código fuente relacionado con las funciones de objetos


Por que subrayar

Recientemente comencé a mirar el código fuente de underscore.js y puse la interpretación del código fuente de underscore.js en mi plan de 2016.

Leer el código fuente de algunas bibliotecas de marcos famosas es como hablar con un maestro, aprenderá mucho. ¿Por qué el subrayado? La razón principal es que el subrayado es corto y conciso (alrededor de 1.5k líneas), encapsula más de 100 métodos útiles, poco acoplamiento, muy adecuado para leer método por método, adecuado para principiantes de JavaScript como el póster original. A partir de él, no solo puede aprender algunos trucos, como usar void 0 en lugar de undefined para evitar que se reescriba undefined, sino también métodos comunes como juicio de tipo variable, función de aceleración y rebote de función, y muchos navegadores compatibles. El truco, también puede aprender las ideas de diseño generales del autor y los principios del diseño de API (compatibilidad con versiones anteriores).

Después de eso, el anfitrión escribirá una serie de artículos para compartir contigo el conocimiento aprendido en la lectura del código fuente.

Bienvenido a ver ~ (Si estás interesado, da la bienvenida a estrella y mira ~) Tu atención es la motivación para que el anfitrión continúe escribiendo

Principal

Hoy, la parte de interpretación del código fuente de Object Functions se ha actualizado.

Si está interesado, puede encontrar que la serie de interpretación anterior del host hablaba sobre métodos de extensión en Object, que es la parte de Funciones de Objeto del código fuente. el subrayado agrega métodos de extensión a 5 tipos, a saber, Objeto -> Matriz -> Colección -> Función -> Utilidad, que es exactamente la secuencia de interpretación del código fuente original (no la secuencia del código fuente). Entre ellos, hay hasta 38 métodos de extensión en Object, lo que no significa que haya demasiados códigos. Por ejemplo, dos líneas de código pueden manejar varios métodos, mientras que el método _.isEqual mencionado en el artículo anterior requiere cientos de Está bien lograrlo. Hoy es el último artículo de la sección de Funciones de objetos. Echemos un vistazo al código fuente de algunos métodos interesantes pero inexplicables que piensa el anfitrión. (De hecho, muchos métodos son simples de usar y muy simples de implementar. Los estudiantes interesados ​​pueden obtener el código fuente por sí mismos)

_.recoger

Primero, echemos un vistazo al método _.pick, que pasa un objeto, luego elimina los pares clave-valor del objeto y devuelve una copia del objeto.

Mira directamente el ejemplo:


_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');

=> {name: 'moe', age: 50}

_.pick({name: 'moe', age: 50, userid: 'moe1'}, ['name', 'age']);

=> {name: 'moe', age: 50}

_.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {

  return _.isNumber(value);

});

=> {age: 50}

De un vistazo, el primer parámetro obj es un objeto y el segundo parámetro puede ser una serie de valores clave, una matriz (la matriz contiene claves) o una función iterativa. Filtramos obj de acuerdo con el valor clave o la función iterativa Devuelve la copia del nuevo objeto.

Si tuviera que diseñar, probablemente juzgaría el tipo en función de los parámetros, y luego escribiría algunos if-else, el contenido de cada rama if-else no tiene nada que ver. Pero la escritura de subrayado es simplemente maravillosa, convirtiendo varias situaciones en una.


// 如果第二个参数是函数

if (_.isFunction(oiteratee)) {

  keys = _.allKeys(obj);

  iteratee = optimizeCb(oiteratee, context);

}

Primero, if-else es inevitable. Si el segundo parámetro que se pasa es function, entonces se pasa la función de iteración. De acuerdo con el contexto (this), se devolverá la nueva función de iteración (OptimizeCb). Este punto no es muy importante, puede ignorarse selectivamente aquí).

Si el segundo parámetro no es una función, las siguientes teclas pueden ser una matriz o varios parámetros paralelos consecutivos. Aquí vamos a utilizar otro método interno importante en subrayado, aplanar. Su función es expandir la matriz anidada. Analizaré este método en el futuro. Solo conozca su función aquí.

else {

  // 如果第二个参数不是函数

  // 则后面的 keys 可能是数组

  // 也可能是连续的几个并列的参数

  keys = flatten(arguments, false, false, 1);

  // 也转为 predicate 函数判断形式

  // 将指定 key 转化为 predicate 函数

  iteratee = function(value, key, obj) { return key in obj; };

  obj = Object(obj);

}

También se convierte a la misma forma que la función iterativa entrante, y se puede juzgar de una manera, y el significado de la variable de claves en los dos casos es diferente, lo cual es realmente muy inteligente. Esto me hace pensar mucho. En muchos casos, el código es redundante. De hecho, probablemente se deba a que mi capacidad de código es demasiado mala. No puedo pensar en hacer esto.

_.crear

El método _.create es muy simple, de acuerdo con el prototipo que le des y algunas propiedades propias, construye un nuevo objeto para devolver.

Da un ejemplo simple:


var Person = function() {};

Person.prototype = {

  show: function() {

    alert(this.name);

  }

};

var me = _.create(Person.prototype, {name: 'hanzichi'});

console.log(me);

// Object {name: "hanzichi"}

//   name: "hanzichi"

//   __proto__: Object

//     show: function()

De hecho, la variable me es un objeto que tiene nombre como sus propias propiedades y se construye con la función Person.

Si el navegador es compatible con ES5, podemos usar Object.create ():


var Person = function() {};

Person.prototype = {

  show: function() {

    alert(this.name);

  }

};

var me = Object.create(Person.prototype);

_.extendOwn(me, {name: 'hanzichi'});

console.log(me);

Si ES5 no es compatible, podemos definir un nuevo constructor, asignar el prototipo del constructor a una variable prototipo conocida y luego usar el nuevo operador para obtener la instancia:


var Person = function() {};

Person.prototype = {

  show: function() {

    alert(this.name);

  }

};

var _Person = function() {};

_Person.prototype = Person.prototype;

var me = new _Person();

_.extendOwn(me, {name: 'hanzichi'});

console.log(me);

La realización de undercore también es aproximadamente la misma.

_.grifo

Originalmente planeé hablar sobre _.tap, pero de repente sentí que sería mejor hablar de ello con llamadas en cadena y cavar un agujero.

resumen

Este es el final del análisis del código fuente de la parte de la función de objetos. Para obtener el código específico, consulte https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8. 3.js # L901-L1269. Aunque he terminado de leer esta parte del código, se necesita tiempo para comprenderlo y digerirlo realmente. Solo puedo decir que entiendo alrededor del 90%. Bienvenido a discutir e intercambiar.

Supongo que te gusta

Origin blog.51cto.com/15080022/2588318
Recomendado
Clasificación