Maison > interface Web > js tutoriel > le corps du texte

Conseils JavaScript

hzc
Libérer: 2020-06-12 10:38:16
avant
1748 Les gens l'ont consulté

Les tableaux peuvent être trouvés partout en JavaScript, et nous pouvons faire beaucoup de choses intéressantes en utilisant le nouvel opérateur de répartition de fonctionnalités dans ECMAScript 6.

1. Itérer sur un tableau vide


Les tableaux créés directement en JavaScript sont lâches, il y aura donc de nombreux pièges. Essayez de créer un tableau à l'aide du constructeur de tableau et vous le comprendrez instantanément.

const arr = new Array(4);
[undefined, undefined, undefined, undefined]
// 谷歌浏览器中是 [empty x 4]
Copier après la connexion

Vous constaterez qu'il est très difficile de parcourir un tableau lâche et d'appeler certaines transformations.

const arr = new Array(4);
arr.map((elem, index) => index);
[undefined, undefined, undefined, undefined]
Copier après la connexion

Pour résoudre ce problème, vous pouvez utiliser Array.apply lors de la création d'un nouveau tableau.

const arr = Array.apply(null, new Array(4));
arr.map((elem, index) => index);
[0, 1, 2, 3]
Copier après la connexion

2. Passez un paramètre vide à la méthode


Si vous souhaitez appeler une méthode et ne renseignez aucun des paramètres, JavaScript le fera signaler une erreur.

method('parameter1', , 'parameter3'); // Uncaught SyntaxError: Unexpected token ,
Copier après la connexion

Une solution courante consiste à passer null ou undefined.

method('parameter1', null, 'parameter3') // or
method('parameter1', undefined, 'parameter3');
Copier après la connexion

Avec l'introduction de l'opérateur spread dans ES6, il existe un moyen plus propre de transmettre des arguments vides à une méthode. Comme mentionné ci-dessus, les tableaux sont lâches, donc leur transmettre des valeurs nulles est OK, et nous en profitons.

method(...['parameter1', , 'parameter3']); // 代码执行了...
Copier après la connexion

3. Déduplication du tableau


Je n'ai jamais compris pourquoi le tableau ne fournit pas de fonction intégrée qui nous permet d'obtenir facilement la valeur dédupliquée . L'opérateur spread nous aide. L'utilisation de l'opérateur spread avec Set peut générer un tableau unique.

const arr = [...new Set([1, 2, 3, 3])];
// [1, 2, 3]
Copier après la connexion

4. Obtenez les éléments d'un tableau de l'arrière vers l'avant


Si vous souhaitez obtenir les éléments d'un tableau de l'arrière vers l'avant, vous pouvez écrire comme ceci :

var arr = [1, 2, 3, 4]

console.log(arr.slice(-1)) // [4]
console.log(arr.slice(-2)) // [3, 4]
console.log(arr.slice(-3)) // [2, 3, 4]
console.log(arr.slice(-4)) // [1, 2, 3, 4]
Copier après la connexion

5. Phrase conditionnelle de court-circuit


Si vous souhaitez exécuter une fonction lorsque la valeur logique d'une certaine condition est vraie, comme ceci :

if (condition) {
  dosomething()
}
Copier après la connexion

À ce stade, vous pouvez utiliser un court-circuit comme ceci :

condition && dosomething()
Copier après la connexion

6. Utilisez l'opérateur "||" pour définir la valeur par défaut<🎜. >


Si vous devez attribuer une valeur par défaut à une variable, qui peut être simplement écrite comme ceci :

var a

console.log(a) // undefined
a = a || &#39;default value&#39;
console.log(a) // default value
a = a || &#39;new value&#39;
console.log(a) // default value
Copier après la connexion

7. Utilisez Object.is() dans la comparaison d'égalité.


nous Nous savons tous que JavasScript est faiblement typé, et lorsque nous utilisons == à des fins de comparaison, dans certains cas, des choses inattendues se produiront en raison de la conversion de type ou de la "conversion de l'un des deux opérandes en l'autre puis comparer" le résultat. Comme ceci :

0 == &#39; &#39; //true
null == undefined //true
[1] == true //true
Copier après la connexion

Par conséquent, JavaScript nous fournit l'opérateur d'égalité ===, qui est plus strict que l'opérateur d'inégalité et ne provoque pas de conversion de type. Mais utiliser === à des fins de comparaison n'est pas la meilleure solution. Vous pouvez obtenir :

NaN === NaN //false
Copier après la connexion

ES6 fournit une nouvelle méthode Object.is(), qui possède certaines fonctionnalités de ===, est meilleure et plus précise, et fonctionne bien dans certains cas particuliers :

Object.is(0 , &#39; &#39;); //false
Object.is(null, undefined); //false
Object.is([1], true); //false
Object.is(NaN, NaN); //true
Copier après la connexion
.

8. Donner une fonction Lier un objet


Nous avons souvent besoin de lier un objet à celui d'une méthode. En JS, si vous souhaitez appeler une fonction et spécifier ceci, vous pouvez utiliser la méthode bind.

Syntaxe de liaison

fun.bind(thisArg[, arg1[, arg2[, ...]]])
Copier après la connexion

Paramètres

thisArg

Lorsque la fonction de liaison est appelée, le Les paramètres serviront de pointeurs vers la fonction d'origine lors de son exécution.

arg1, arg2, …

Lorsque la fonction liée est appelée, ces paramètres seront transmis à la méthode liée avant les paramètres réels.

Valeur de retour

Renvoie une copie de la fonction originale modifiée par cette valeur et les paramètres d'initialisation spécifiés

Instance dans JS

const myCar = {
 brand: &#39;Ford&#39;,
 type: &#39;Sedan&#39;,
 color: &#39;Red&#39;
};

const getBrand = function () {
 console.log(this.brand);
};

const getType = function () {
 console.log(this.type);
};

const getColor = function () {
 console.log(this.color);
};

getBrand(); // object not bind,undefined

getBrand(myCar); // object not bind,undefined

getType.bind(myCar)(); // Sedan

let boundGetColor = getColor.bind(myCar);
boundGetColor(); // Red
Copier après la connexion


9. Obtenez l'extension de fichier

Solution 1 : Expression régulière

function getFileExtension1(filename) {
  return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}
Copier après la connexion

Solution 2 : Méthode split de String

function getFileExtension2(filename) {
  return filename.split(&#39;.&#39;).pop();
}
Copier après la connexion

Ces deux solutions ne peuvent pas résoudre certains cas extrêmes. Il existe une autre solution plus puissante.

Solution 3 : méthodes slice et lastIndexOf de String

function getFileExtension3(filename) {
  return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
}

console.log(getFileExtension3(&#39;&#39;));                            // &#39;&#39;
console.log(getFileExtension3(&#39;filename&#39;));                    // &#39;&#39;
console.log(getFileExtension3(&#39;filename.txt&#39;));                // &#39;txt&#39;
console.log(getFileExtension3(&#39;.hiddenfile&#39;));                 // &#39;&#39;
console.log(getFileExtension3(&#39;filename.with.many.dots.ext&#39;)); // &#39;ext&#39;
Copier après la connexion


Comment cela est-il implémenté ?

    <🎜 Le >String. La méthode lastIndexOf() renvoie la dernière position où la valeur spécifiée ('.' dans cet exemple) apparaît dans la chaîne qui appelle cette méthode, ou -1 si elle n'est pas trouvée.
  • Pour 'filename' et '.hiddenfile', les valeurs de retour de lastIndexOf sont respectivement 0 et -1. L'opérateur de décalage à droite non signé (»>) convertit -1 en. 4294967295, convertissez -2 en 4294967294. Cette méthode peut garantir que le nom du fichier reste inchangé dans les cas extrêmes.
  • String.prototype.slice() Extrait l'extension du fichier de l'index calculé ci-dessus. Si l'index est plus grand que la longueur du nom de fichier, le résultat est "".
10. Empêcher les attaques non appliquées

Réécrire la méthode prototype de l'objet intégré Le code externe peut être exposé par réécriture. le code et les fonctions qui modifient les paramètres liés. Il s'agit d'un problème de sécurité sérieux lors de l'utilisation de polyfills sous l'approche es5.
// bind polyfill 示例
function bind(fn) {
  var prev = Array.prototype.slice.call(arguments, 1);
  return function bound() {
    var curr = Array.prototype.slice.call(arguments, 0);
    var args = Array.prototype.concat.apply(prev, curr);
    return fn.apply(null, args);
  };
}


// unapply攻击
function unapplyAttack() {
  var concat = Array.prototype.concat;
  Array.prototype.concat = function replaceAll() {
    Array.prototype.concat = concat; // restore the correct version
    var curr = Array.prototype.slice.call(arguments, 0);
    var result = concat.apply([], curr);
    return result;
  };
}
Copier après la connexion

上面的函数声明忽略了函数bind的prev参数,意味着调用unapplyAttack之后首次调用.concat将会抛出错误。

使用Object.freeze,可以使对象不可变,你可以防止任何内置对象原型方法被重写。

(function freezePrototypes() {
  if (typeof Object.freeze !== &#39;function&#39;) {
    throw new Error(&#39;Missing Object.freeze&#39;);
  }
  Object.freeze(Object.prototype);
  Object.freeze(Array.prototype);
  Object.freeze(Function.prototype);
}());
Copier après la connexion

11.Javascript多维数组扁平化


下面是将多位数组转化为单一数组的三种不同方法。

var arr = [[1, 2],[3, 4, 5], [6, 7, 8, 9]];
Copier après la connexion

期望结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
Copier après la connexion

解决方案1:使用concat()和apply()

var newArr = [].concat.apply([], arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copier après la connexion

解决方案2:使用reduce()

var newArr = arr.reduce(function(prev, curr) {
  return prev.concat(curr);
});
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copier après la connexion

解决方案3:使用 ES6 的展开运算符

var newArr = [].concat(...arr);
console.log(newArr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Copier après la connexion

12. 函数中如何使用可选参数(包括可选回调函数)


实例函数中第2个与第3个参数为可选参数

function example( err, optionA, optionB, callback ) {
        // 使用数组取出arguments
        var args = new Array(arguments.length);
        for(var i = 0; i < args.length; ++i) {
            args[i] = arguments[i];
        };
        
        // 第一个参数为错误参数
        // shift() 移除数组中第一个参数并将其返回
        err = args.shift();

        // 如果最后一个参数是函数,则它为回调函数
        // pop() 移除数组中最后一个参数并将其返回
        if (typeof args[args.length-1] === &#39;function&#39;) { 
            callback = args.pop();
        }
        
        // 如果args中仍有元素,那就是你需要的可选参数
        // 你可以像这样一个一个的将其取出:
        if (args.length > 0) optionA = args.shift(); else optionA = null;
        if (args.length > 0) optionB = args.shift(); else optionB = null;

        // 像正常一样继续:检查是否有错误
        if (err) { 
            return callback && callback(err);
        }
        
        // 打印可选参数
        console.log(&#39;optionA:&#39;, optionA);
        console.log(&#39;optionB:&#39;, optionB);
        console.log(&#39;callback:&#39;, callback);

        /* 你想做的逻辑 */

    }

    // ES6语法书写更简短
    function example(...args) {
        // 第一个参数为错误参数
        const err = args.shift();
        // 如果最后一个参数是函数,则它为回调函数
        const callback = (typeof args[args.length-1] === &#39;function&#39;) ? args.pop() : null;

        // 如果args中仍有元素,那就是你需要的可选参数你可以像这样一个一个的将其取出:
        const optionA = (args.length > 0) ? args.shift() : null;
        const optionB = (args.length > 0) ? args.shift() : null;
        // ... 重复取更多参数

        if (err && callback) return callback(err);

        /* 你想做的逻辑 */
    }
Copier après la connexion

推荐教程:《JS教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
js
source:juejin.im
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal