Maison >interface Web >js tutoriel >Souligner les compétences d'analyse du code source_javascript
Il y a quelques années, certaines personnes disaient que JavaScript était le langage de programmation le plus sous-estimé. Depuis l'émergence de nodejs, le concept All Stack/Full Stack est devenu de plus en plus populaire. . JavaScript est un langage de type C. Si vous disposez d'une base en langage C, vous pouvez généralement comprendre le code JavaScript. Cependant, en tant que langage de script, la flexibilité de JavaScript est bien inférieure à celle du C, ce qui entraînera également certaines difficultés. apprentissage.
1. Rassemblement
1. La première consiste en plusieurs méthodes itératives.
_.each = _.forEach = function(obj, iteratee, context) { iteratee = optimizeCb(iteratee, context); var i, length; if (isArrayLike(obj)) { for (i = 0, length = obj.length; i < length; i++) { iteratee(obj[i], i, obj); } } else { var keys = _.keys(obj); for (i = 0, length = keys.length; i < length; i++) { iteratee(obj[keys[i]], keys[i], obj); } } // 链式调用 return obj; };
ES ajoute également une méthode native forEach() aux tableaux. La différence est que la méthode each(forEach) ici peut être utilisée pour toutes les collections et que la fonction accepte trois paramètres (collection, fonction d'itération, environnement d'exécution).
La fonction optimiseCb lie les environnements d'exécution correspondants à différentes méthodes d'itération en fonction du nombre de paramètres de la fonction d'itération. La fonction d'itération forEach accepte également trois paramètres (valeur, index, ensemble).
L'étape suivante consiste à appeler la fonction d'itération dans la boucle for.
Une implémentation plus élégante du jugement isArrayLike dans _.map : (une seule boucle for)
var keys = !isArrayLike(obj) && _.keys(obj), length = (keys || obj).length, results = Array(length); for (var index = 0; index < length; index++) { var currentKey = keys ? keys[index] : index; results[index] = iteratee(obj[currentKey], currentKey, obj); } return results; // 合理使用&&、||、?:可以大大减少代码量
Il y a deux autres endroits spéciaux :
•Divisez les collections en collections de type tableau et en collections d'objets. La fonction isArrayLike est utilisée :
// js的最大精确整数 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; var isArrayLike = function(collection) { var length = collection != null && collection.length; return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; }; // 如果集合有Length属性且为数字并且大于0小于最大的精确整数,则判定是类数组
•La fonction _.keys est utilisée. Object a également une fonction de clés natives, qui est utilisée pour renvoyer un tableau d'attributs pouvant être énumérés par obj. L'implémentation est relativement simple, grâce à la méthode hasOwnProperty().
-------------------------------------------------------------- --- ------------------------------------
Les méthodes _.map, _.reduce ont des principes similaires.
La fonction _.find est similaire à Array.some(), sauf qu'elle renvoie le premier élément qui rend le résultat de l'itération vrai, au lieu de renvoyer une valeur booléenne comme Array.some().
_.find = _.detect = function(obj, predicate, context) { var key; if (isArrayLike(obj)) { key = _.findIndex(obj, predicate, context); } else { key = _.findKey(obj, predicate, context); } if (key !== void 0 && key !== -1) return obj[key]; }; function createIndexFinder(dir) { return function(array, predicate, context) { predicate = cb(predicate, context); var length = array != null && array.length; // 如果dir为1,index为0,index+=1,index正序循环 // 如果dir 为-1,index为length-1,index += -1反序循环 // 判断循环条件则用了index >= 0 && index < length方法兼顾两种循环方式 var index = dir > 0 ? 0 : length - 1; for (; index >= 0 && index < length; index += dir) { if (predicate(array[index], index, array)) return index; } return -1; }; } _.findIndex = createIndexFinder(1); _.findLastIndex = createIndexFinder(-1);
Ce qui vaut la peine d'être appris, c'est qu'une boucle for ici peut configurer différentes séquences de boucles en fonction des différents paramètres transmis.
1. Les autres méthodes de la collection sont essentiellement implémentées sur la base de méthodes itératives.
_.max = function(obj, iteratee, context) { var result = -Infinity, lastComputed = -Infinity, value, computed; if (iteratee == null && obj != null) { obj = isArrayLike(obj) ? obj : _.values(obj); for (var i = 0, length = obj.length; i < length; i++) { value = obj[i]; if (value > result) { result = value; } } } else { iteratee = cb(iteratee, context); _.each(obj, function(value, index, list) { computed = iteratee(value, index, list); if (computed > lastComputed || computed === -Infinity && result === -Infinity) { result = value; lastComputed = computed; } }); } return result; };
La méthode max est utilisée pour trouver la valeur maximale dans l'ensemble, en parcourant tous les éléments de la liste, puis en comparant l'élément actuel et l'élément résultat. Si l'élément actuel est supérieur au résultat, il est attribué. à l'élément de résultat, et enfin l'élément de résultat est renvoyé.
2. Convertir la collection en tableau
_.toArray = function(obj) { if (!obj) return []; // 如果是数组,采用了Array.prototype.slice.call(this,obj)这种方法 if (_.isArray(obj)) return slice.call(obj); // 类数组对象,这里没有采用Slice方法,而是利用.map对集合进行迭代,从而返回一个数组。 _.identity该方法传入的值和返回的值相等。(主要用于迭代) if (isArrayLike(obj)) return _.map(obj, _.identity); // 普通对象,则返回由属性值组成的数组。 return _.values(obj); };
Type de données
STL doit distinguer les vecteurs, les listes, etc. car différentes structures de données nécessitent ou peuvent être implémentées différemment, mais quelle est la raison de la séparation des collections et des tableaux en trait de soulignement ? Cela commence également par le type de données JavaScript, voir l'image ci-dessous.