Heim  >  Artikel  >  Web-Frontend  >  Sprechen Sie über den Void-Operator in Javascript

Sprechen Sie über den Void-Operator in Javascript

高洛峰
高洛峰Original
2016-12-13 13:24:481340Durchsuche

Da JS-Ausdrücke in der Regel umständlich sind, verwende ich seit kurzem Coffeescript, um den Aufwand zu verringern. Wenn ich beispielsweise den ersten Hund im Haus abrufen möchte, muss ich zunächst feststellen, ob das Hausobjekt vorhanden ist, dann feststellen, ob house.dogs vorhanden ist, und schließlich house.dogs[0] abrufen. In JS muss ich so schreiben

var dog = (typeof house !== 'undefined && house !== null) && house.dogs && house.dogs[0]

In Coffee muss ich nur so schreiben:

dog = house?.dogs?[0];

An diesem Punkt werden sich die Leser fragen, ob das etwas hat mit dem Titel „void in Javascript“ zu tun. Gibt es eine Dime-Beziehung? Die Essenz von Coffee ist JS. Der Grund, warum Coffee so gut funktioniert, liegt darin, dass es effizienten und robusten JS-Code generiert.

var dog, _ref;
dog = typeof house !== "undefined" && house !== null ? (_ref = house.dogs) != null ? _ref[0] : void 0 : void 0;

Nur ​​eine Zeile Coffee-Code hat einen so langen JS-Code generiert, der zuverlässiger und sicherer zu sein scheint als der, den ich zuvor in JS geschrieben habe. Am Ende stehen auch zwei leere Nullen ist das?

Strukturieren Sie das obige Beispiel:

dog = (typeof house !== "undefined" && house !== null) ? 
        ((_ref = house.dogs) != null ? _ref[0] : void 0 ) 
        : void 0;

Wenn Haus undefiniert oder Haus null ist, geben Sie void 0 zurück

Wenn house.dogs null ist, geben Sie void 0 zurück

Aber was ist der Wert von void 0? Das ist leicht zu testen:

typeof void 0 //得到"undefined"console.log(void 0) //输出undefined

Es scheint, dass void 0 undefiniert ist, aber diese Methode ist zu wild und nicht streng genug, das ist nicht möglich Um zu antworten: Was sind die Werte der unzähligen möglichen Kombinationen von void 100, void hello(), void i++?

Werfen wir einen Blick auf die Normen.

Die Spezifikation besagt Folgendes

In der ECMAScript 262-Spezifikation gibt es die folgende Beschreibung:

The void Operator
The production UnaryExpression : void UnaryExpression is evaluated as follows:
Let expr be the result of evaluating UnaryExpression.
Call GetValue(expr).
Return undefined.
NOTE: GetValue must be called even though its value is not used because it may have observable side-effects.

Übersetzung:

void操作符
产生式 UnaryExpression : void UnaryExpression 按如下流程解释:
令 expr 为解释执行UnaryExpression的结果。
调用 GetValue(expr).
返回 undefined.
注意:GetValue一定要调用,即使它的值不会被用到,但是这个表达式可能会有副作用(side-effects)。

Der Schlüssel Der Punkt ist: Unabhängig vom Ausdruck nach void gibt der void-Operator undefiniert zurück. Daher können wir uns den von Coffee oben kompilierten Code wie folgt vorstellen:

dog = (typeof house !== "undefined" && house !== null) ? 
        ((_ref = house.dogs) != null ? _ref[0] : undefined ) 
        : undefined ;

Das Problem ist, da (void 0) === undefiniert, würde es nicht ausreichen, einfach undefiniert zu schreiben?

Warum void verwenden?

Weil undefiniert kein reserviertes Wort in Javascript ist. Mit anderen Worten, Sie können Folgendes schreiben:

function joke() {
    var undefined = "hello world";
    console.log(undefined); //会输出"hello world"
}
console.log(undefined); //输出undefined

Ja, Sie können undefiniert als Variablennamen in einem Funktionskontext verwenden, sodass der in diesem Kontext geschriebene Code nur aus dem globalen Bereich in undefiniert abgerufen werden kann , wie zum Beispiel:

window.undefined //浏览器环境
GLOBAL.undefined //Node环境

Aber es sollte beachtet werden, dass selbst wenn window, GLOBAL immer noch im Funktionskontext definiert werden kann, sodass es nicht 100 % zuverlässig ist, von window/GLOBAL undefiniert zu werden. Zum Beispiel:

function x() {
   var undefined = 'hello world',
       f = {},
       window = {
           'undefined': 'joke'
       };
   console.log(undefined);// hello world
   console.log(window.undefined); //joke
   console.log(f.a === undefined); //false
   console.log(f.a === void 0); //true
}

Daher ist die Verwendung von void zum Erhalten von undefiniert zu einer allgemeinen Regel geworden. Beispielsweise wird isUndefiniert in underscore.js wie folgt geschrieben:

_.isUndefined = function(obj) {
    return obj === void 0;
}

Gibt es neben der Verwendung von void, um sicherzustellen, dass der undefinierte Wert erhalten wird, noch andere Methoden? Ja, eine andere Möglichkeit ist der Funktionsaufruf. Beispielsweise verwendet der Quellcode von AngularJS diese Methode:

(function(window, document, undefined) {    //.....
})(window, document);

Durch die Nichtübergabe von Parametern wird sichergestellt, dass der Wert des undefinierten Parameters undefiniert ist.

Andere Funktionen

Gibt es außer der Verwendung von undefiniert noch andere Verwendungsmöglichkeiten für void?

Es gibt auch eine gemeinsame Funktion, das Ausfüllen von href. Unten sehen Sie einen Screenshot von Weibo. Seine Reposts, Sammlungen und Diskussionen sind alles Hyperlinks, aber Benutzer erwarten nicht, dass sie durch Klicken auf eine andere Seite springen, sondern einige interaktive Vorgänge auslösen.

Sprechen Sie über den Void-Operator in Javascript

Theoretisch haben diese drei Hyperlinks keine URL, aber wenn Sie sie nicht schreiben, hehe, wird durch Klicken darauf die gesamte Seite aktualisiert. Deshalb haben wir href="javascript:void(0) verwendet, um sicherzustellen, dass beim Klicken darauf ein rein langweiliges void(0) ausgeführt wird.

Eine andere Situation ist, wenn wir ein leeres src-Bild generieren möchten, der beste Weg scheint src='javascript:void(0)' zu sein

Am Ende geschrieben

Zurück zur Definition von void: Es gibt einen Satz, der besonders verwirrend ist:

Hinweis: GetValue muss aufgerufen werden, auch wenn sein Wert nicht verwendet wird, dieser Ausdruck kann jedoch Nebenwirkungen haben

.

这是什么意思?这表示无论void右边的表达式是什么,都要对其求值。这么说可能不太明白,在知乎上winter大神有过阐述关于js中void,既然返回永远是undefined,那么GetValue有啥用?,我且拾人牙慧,代入一个场景,看代码:

var happiness = 10;
var girl = {
    get whenMarry() {
        happiness--;
        return 1/0; //Infinity
    },
    get happiness() {
        return happiness;
    }
};

console.log(girl.whenMarry); //调用了whenMarry的get方法
console.log(girl.happiness); // 9

void girl.whenMarry; //调用了whenMarry的get方法
console.log(girl.happiness); // 8

delete girl.whenMarry; //没有调用whenMarry的get方法
console.log(girl.happiness); //还是8

上述代码定义了一个大龄文艺女青年,每被问到什么时候结婚呀(whenMarry),happiness都会减1。从执行情况可以看出,无论是普通访问girl.whenMarry,还是void girl.whenMarry都会使她的happiness--。而如果把void换成delete操作符写成delete girl.whenMarry,她的happiness就不会减了,因为delete操作符不会对girl.whenMarry求值。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn