Maison  >  Article  >  interface Web  >  Conseils JavaScript

Conseils JavaScript

hzc
hzcavant
2020-06-12 10:38:161729parcourir

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]

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]

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]

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 ,

Une solution courante consiste à passer null ou undefined.

method('parameter1', null, 'parameter3') // or
method('parameter1', undefined, 'parameter3');

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']); // 代码执行了...

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]

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]

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()
}

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

condition && dosomething()

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 || 'default value'
console.log(a) // default value
a = a || 'new value'
console.log(a) // default value

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 == ' ' //true
null == undefined //true
[1] == true //true

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

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 , ' '); //false
Object.is(null, undefined); //false
Object.is([1], true); //false
Object.is(NaN, NaN); //true
.

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[, ...]]])

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: 'Ford',
 type: 'Sedan',
 color: 'Red'
};

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


9. Obtenez l'extension de fichier

Solution 1 : Expression régulière

function getFileExtension1(filename) {
  return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined;
}

Solution 2 : Méthode split de String

function getFileExtension2(filename) {
  return filename.split('.').pop();
}

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(''));                            // ''
console.log(getFileExtension3('filename'));                    // ''
console.log(getFileExtension3('filename.txt'));                // 'txt'
console.log(getFileExtension3('.hiddenfile'));                 // ''
console.log(getFileExtension3('filename.with.many.dots.ext')); // 'ext'


Comment cela est-il implémenté ?

    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;
  };
}

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

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

(function freezePrototypes() {
  if (typeof Object.freeze !== 'function') {
    throw new Error('Missing Object.freeze');
  }
  Object.freeze(Object.prototype);
  Object.freeze(Array.prototype);
  Object.freeze(Function.prototype);
}());

11.Javascript多维数组扁平化


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

var arr = [[1, 2],[3, 4, 5], [6, 7, 8, 9]];

期望结果:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

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

var newArr = [].concat.apply([], arr);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]

解决方案2:使用reduce()

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

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

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

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);

        /* 你想做的逻辑 */
    }

推荐教程:《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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer