ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript の void 演算子について話します。

JavaScript の void 演算子について話します。

高洛峰
高洛峰オリジナル
2016-12-13 13:24:481340ブラウズ

JSの表現が冗長になりがちなので、負担を軽減するために最近Coffeescriptを使い始めました。たとえば、家の最初の犬を取得したい場合は、まず house オブジェクトが存在するかどうかを判断し、次に house.dogs が存在するかどうかを判断し、最後に house.dogs[0] を取得する必要があります。 JS では、次のように書く必要があります

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

Coffee では、次のように書くだけです:

dog = house?.dogs?[0];

これを書いた後、読者は、これはタイトルの "void in Javascript" と何か関係があるのか​​と尋ねるでしょう。 Coffee の本質は JS です。Coffee が非常にうまく機能する理由は、Coffee が効率的で堅牢な JS コードを生成するためです。生成された結果を見てみましょう。

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

Coffee コードのたった 1 行で、これほど長い JS コードが生成されました。これは、以前に JS で書いたコードよりも信頼性が高く、安全であると思われます。最後には void が 2 つあります。これは誰ですか?

上記の例を構造化します:

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

houseが未定義またはhouseがnullの場合、void 0が返されます

house.dogsがnullの場合、void 0が返されます

しかし、void 0の値は何ですか?テストが簡単:

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

void 0 は未定義のようですが、この方法は乱暴すぎて厳密さが足りません。つまり、答えることは不可能です: void の無数の可能な組み合わせの値は何ですか100、void hello()、void i++?

規格の内容を見てみましょう。

仕様にはこう書いてあります

ECMAScript 262 仕様には次のような記述があります:

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.

翻訳:

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

重要な点は、 void の後の式が何であっても、void 演算子は未定義を返すということです。 、上記は次のようになります。 Coffee によってコンパイルされたコードは次のように考えることができます:

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

質問は、 (void 0) === 未定義であるため、単に unknown と書くだけで十分ではないでしょうか?

なぜ void を使用するのですか?

未定義はJavaScriptの予約語ではないからです。つまり、次のように書くことができます:

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

はい、関数コンテキストで変数名として unknown を使用できます。そのため、このコンテキストで記述されたコードは、次のようにグローバル スコープからのみ unknown を取得できます:

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

しかし、それはwindow の場合でも、関数コンテキストで GLOBAL を定義できるため、window/GLOBAL から unknown を取得することは 100% 信頼できるわけではないことに注意してください。例:

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
}

そのため、void を使用して未定義を取得するのが一般的なルールになりました。たとえば、underscore.js の isUnknown は次のように記述されます:

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

未定義の値を確実に取得するために void を使用する以外に、他の方法はありますか?はい、もう 1 つの方法は関数呼び出しを使用することです。たとえば、AngularJS のソース コードでは次のメソッドが使用されています:

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

パラメーターを渡さないことで、未定義パラメーターの値が未定義であることが保証されます。

その他の関数

未定義を取得する以外に、void の用途はありますか?

hrefを埋めるという共通の関数もあります。以下は Weibo のスクリーンショットです。その転送、お気に入り、ディスカッションはすべてハイパーリンクですが、ユーザーはそれらをクリックして別のページにジャンプするのではなく、何らかのインタラクティブな操作をトリガーしたいと考えています。

JavaScript の void 演算子について話します。

理論的には、これら 3 つのハイパーリンクには URL がありませんが、書かないと、ふふふ、クリックするとページ全体が更新されます。そこで、クリックするとまったく退屈な void(0) が実行されるようにするために、 href="javascript:void(0) を使用しました。

別の状況では、空の src 画像を生成したい場合、最良の方法は src= のようです。 'javascript:void(0)'

最後に書いてあります

void の定義に戻ると、特に混乱を招く文があります:

注: 値が使用されない場合でも、GetValue を呼び出す必要があります。ただし、この式には副作用がある可能性があります

这是什么意思?这表示无论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求值。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。