Heim >Web-Frontend >js-Tutorial >JavaScript-Tipps

JavaScript-Tipps

hzc
hzcnach vorne
2020-06-12 10:38:161783Durchsuche

Arrays sind überall in JavaScript zu finden, und mit dem neuen Feature-Spread-Operator in ECMAScript 6 können wir viele tolle Dinge tun.

1. Über ein leeres Array iterieren


Direkt in JavaScript erstellte Arrays sind lose, daher gibt es viele Fallstricke. Versuchen Sie, mit dem Array-Konstruktor ein Array zu erstellen, und Sie werden es sofort verstehen.

const arr = new Array(4);
[undefined, undefined, undefined, undefined]
// 谷歌浏览器中是 [empty x 4]

Sie werden feststellen, dass es sehr schwierig ist, ein loses Array zu durchlaufen und einige Transformationen aufzurufen.

const arr = new Array(4);
arr.map((elem, index) => index);
[undefined, undefined, undefined, undefined]

Um dieses Problem zu lösen, können Sie Array.apply verwenden, wenn Sie ein neues Array erstellen.

const arr = Array.apply(null, new Array(4));
arr.map((elem, index) => index);
[0, 1, 2, 3]

2. Übergeben Sie einen leeren Parameter an die Methode


Wenn Sie eine Methode aufrufen und keinen der Parameter ausfüllen möchten, wird JavaScript dies tun einen Fehler melden.

method('parameter1', , 'parameter3'); // Uncaught SyntaxError: Unexpected token ,

Eine gängige Lösung besteht darin, null oder undefiniert zu übergeben.

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

Mit der Einführung des Spread-Operators in ES6 gibt es eine sauberere Möglichkeit, leere Argumente an eine Methode zu übergeben. Wie oben erwähnt, sind Arrays lose, daher ist die Übergabe von Nullwerten an sie in Ordnung, und wir nutzen dies aus.

method(...['parameter1', , 'parameter3']); // 代码执行了...

3. Array-Deduplizierung


Ich habe nie verstanden, warum das Array keine integrierte Funktion bietet, die es uns ermöglicht, den deduplizierten Wert einfach zu erhalten . . Der Spread-Operator hilft uns, den Spread-Operator mit Set zu verwenden, um ein eindeutiges Array zu generieren.

const arr = [...new Set([1, 2, 3, 3])];
// [1, 2, 3]

4. Array-Elemente von hinten nach vorne abrufen


Wenn Sie die Elemente eines Arrays von hinten nach vorne abrufen möchten, können Sie Folgendes schreiben: Dies:

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. Kurzschluss-Bedingungssatz


Wenn Sie eine Funktion ausführen möchten, wenn der logische Wert einer bestimmten Bedingung wahr ist, z Dies:

if (condition) {
  dosomething()
}

Zu diesem Zeitpunkt können Sie einen Kurzschluss wie folgt verwenden:

condition && dosomething()

6. Verwenden Sie den Operator „||“, um den Standardwert festzulegen


Wenn Sie einer Variablen einen Standardwert zuweisen müssen, kann dieser einfach so geschrieben werden:

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. Verwenden Sie Object.is() im Gleichheitsvergleich


uns Wir alle wissen, dass JavaScript schwach typisiert ist, und wenn wir == zum Vergleich verwenden, passieren in einigen Fällen unerwartete Dinge aufgrund der Typkonvertierung oder der „Konvertierung eines der beiden Operanden in den anderen“. und dann das Ergebnis vergleichen. So:

0 == ' ' //true
null == undefined //true
[1] == true //true

Daher stellt uns JavaScript den Gleichheitsoperator === zur Verfügung, der strenger als der Ungleichheitsoperator ist und keine Typkonvertierung verursacht. Die Verwendung von === zum Vergleich ist jedoch nicht die beste Lösung. Sie erhalten möglicherweise:

NaN === NaN //false

ES6 bietet eine neue Object.is()-Methode, die einige Funktionen von === aufweist, besser und präziser ist und in einigen Sonderfällen eine gute Leistung erbringt:

Object.is(0 , ' '); //false
Object.is(null, undefined); //false
Object.is([1], true); //false
Object.is(NaN, NaN); //true

8. Geben Sie eine Funktion an. Binden Sie ein Objekt


Wir müssen oft ein Objekt an diese Methode binden. Wenn Sie in JS eine Funktion aufrufen und diese angeben möchten, können Sie die Bind-Methode verwenden.

Bind-Syntax

fun.bind(thisArg[, arg1[, arg2[, ...]]])

Parameter

thisArg

Wenn die Bindungsfunktion aufgerufen wird, wird die The Parameter dienen als Zeiger auf die ursprüngliche Funktion, wenn diese ausgeführt wird.

arg1, arg2, …

Wenn die gebundene Funktion aufgerufen wird, werden diese Parameter vor den tatsächlichen Parametern an die gebundene Methode übergeben.

Rückgabewert

Gibt eine Kopie der Originalfunktion zurück, die durch den angegebenen Wert und die Initialisierungsparameter geändert wurde

Instanz in 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. Holen Sie sich die Dateierweiterung

Lösung 1: Regulärer Ausdruck

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

Lösung 2: Die Split-Methode von String

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

Diese beiden Lösungen können einige Randfälle nicht lösen. Es gibt eine andere leistungsfähigere Lösung.

Lösung 3: Strings Slice- und lastIndexOf-Methoden

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'


Wie wird das implementiert?

  • String. Die Methode lastIndexOf() gibt die letzte Position zurück, an der der angegebene Wert (in diesem Beispiel „.“) in der Zeichenfolge vorkommt, die diese Methode aufruft, oder -1, wenn er nicht gefunden wird.

  • Für „filename“ und „.hiddenfile“ sind die Rückgabewerte von lastIndexOf jeweils 0 und -1. Der vorzeichenlose Rechtsverschiebungsoperator (»>) konvertiert -1 in 4294967295, Konvertieren Sie -2 in 4294967294. Diese Methode kann sicherstellen, dass der Dateiname in Randfällen unverändert bleibt.

  • String.prototype.slice() Extrahiert die Erweiterung der Datei aus dem oben berechneten Index. Ist der Index größer als die Länge des Dateinamens, ist das Ergebnis „“.

10. Unapply-Angriffe verhindern


Die Prototypmethode des integrierten Objekts kann durch Umschreiben offengelegt werden den Code und Funktionen, die gebundene Parameter ändern. Dies ist ein ernstes Sicherheitsproblem bei der Verwendung von Polyfills im Rahmen des es5-Ansatzes.

// 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教程

Das obige ist der detaillierte Inhalt vonJavaScript-Tipps. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen