`var {...} = ...`语句中的花括号是做什么的?

时间:2013-03-08 09:44:52

标签: javascript ecmascript-6 destructuring javascript-1.7

不确定这是否是特定于Mozilla的JS语法,但我经常发现变量是以这种方式声明的,例如,在add-on SDK docs中:

var { Hotkey } = require("sdk/hotkeys");

并使用各种chrome Javascript(let语句代替var),

let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;

我发现它非常令人困惑但我无法找到有关这两种语法的任何文档,即使在MDN上也是如此。

4 个答案:

答案 0 :(得分:70)

你正在看的是一个解构分配。它是Haskell中pattern matching的一种形式。

使用解构赋值,您可以从对象和数组中提取值,并使用对象和数组文字语法将它们分配给新声明的变量。这使代码更加简洁。

例如:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a, b, c} = ascii;

以上代码相当于:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var a = ascii.a;
var b = ascii.b;
var c = ascii.c;

类似于数组:

var ascii = [97, 98, 99];

var [a, b, c] = ascii;

这相当于:

var ascii = [97, 98, 99];

var a = ascii[0];
var b = ascii[1];
var c = ascii[2];

您也可以使用let提取和重命名对象属性,如下所示:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

let {a: A, b: B, c: C} = ascii;

这相当于:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var A = ascii.a;
var B = ascii.b;
var C = ascii.c;

这就是它的全部内容。

答案 1 :(得分:62)

它们都是JavaScript 1.7的功能。第一个是block-level variables

  

let允许您声明变量,将其范围限制为使用它的块,语句或表达式。这与var关键字不同,>>> a, (b, c) = (1, (2, 3)) >>> a, b, c (1, 2, 3) 关键字全局定义变量,或者无论块范围如何,都在本地定义整个函数。

第二个名为destructuring

  

解构赋值可以使用反映数组和对象文字构造的语法从数组或对象中提取数据。
  ...
  使用解构赋值可以做的一件特别有用的事情是在单个语句中读取整个结构,尽管可以使用它们执行许多有趣的操作,如后面的示例部分所示。

对于那些熟悉Python的人来说,它与这种语法类似:

var {Hotkey: Hotkey} = require("sdk/hotkeys");
// Or
var Hotkey = require("sdk/hotkeys").Hotkey;

第一个代码块是:

的简写
let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;

您可以将第二个代码块重写为:

{{1}}

答案 2 :(得分:1)

这是Javascript中的破坏性工作,并且是ES2015标准的一部分。它可以将数组中的值解压缩或从对象中提取属性,或将其提取到不同的变量中。 例如:阵列解构

public class AlarmReceiver extends BroadcastReceiver {

private NotificationManager mNotificationManager;
// Notification ID.
private static final int NOTIFICATION_ID = 0;
// Notification channel ID.
private static final String PRIMARY_CHANNEL_ID =
        "primary_notification_channel";

private ArrayList<Proverb> theListOfAll;
private Proverb theFirstQuote;
private String theNotification;
private short dID;
private String dProverb;
private String dSource;

private Proverb getRandom() {
    Proverb result;
    int i = (int) Math.floor(Math.random() * theListOfAll.size());
    result = theListOfAll.get(i);
    return result;
}


@Override
public void onReceive(Context context, Intent intent) {

    theListOfAll = new ArrayList<>();
    theListOfAll.add(new Proverb((short) 0, "The secret of getting ahead is getting started.", "Mark Twain"));
    theFirstQuote = theListOfAll.get(0);
    theNotification = theFirstQuote.getProverb() + " " + theFirstQuote.getTheSource();//this works

    mNotificationManager = (NotificationManager)
            context.getSystemService(Context.NOTIFICATION_SERVICE);

    //get the quote
    setLoadingQue(Volley.newRequestQueue(context));//this isn't working
    // Deliver the notification.
    deliverNotification(context);//this works, sends the notification formed a few lines above
}


private RequestQueue loadingQue;

/**
 * Adapted from StackOverflow
 */
public void setLoadingQue(RequestQueue loadingQue) {
    this.loadingQue = loadingQue;
    JsonArrayRequest arrReq = new JsonArrayRequest(Request.Method.GET, "http://myjson.com/r5mps",
            new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    // Check the length of our response (to see if the user has any repos)
                    if (response.length() > 0) {
                        // The user does have repos, so let's loop through them all.
                        for (int i = 0; i < response.length(); i++) {
                            try {
                                JSONObject jsonObject = response.getJSONObject(i);
                                dID = (short) jsonObject.getInt("id");
                                dProverb = jsonObject.getString("text").trim();
                                dSource = jsonObject.getString("source").trim() + " ";
                                theListOfAll.add(new Proverb(dID, dProverb, dSource));
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    theFirstQuote = getRandom();
                    theNotification = theFirstQuote.getProverb() + " " + theFirstQuote.getTheSource();
                }
            },

            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    System.out.println(error);
                }
            }
    );
    // Add the request we just defined to our request queue.
    // The request queue will automatically handle the request as soon as it can.
    loadingQue.add(arrReq);
}

/**
 * Builds and delivers the notification.
 *
 * @param context, activity context.
 */
private void deliverNotification(Context context) {
    // Create the content intent for the notification, which launches
    // this activity
    Intent contentIntent = new Intent(context, MainActivity.class);

    PendingIntent contentPendingIntent = PendingIntent.getActivity
            (context, NOTIFICATION_ID, contentIntent, PendingIntent
                    .FLAG_UPDATE_CURRENT);
    // Build the notification
    NotificationCompat.Builder builder = new NotificationCompat.Builder
            (context, PRIMARY_CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_stand_up)
            .setContentTitle(context.getString(R.string.notification_title))
            .setContentIntent(contentPendingIntent)
            .setStyle(new NotificationCompat.BigTextStyle()
                    .bigText(theNotification))
            .setPriority(NotificationCompat.PRIORITY_HIGH)
            .setAutoCancel(true)
            .setDefaults(NotificationCompat.DEFAULT_ALL);

    // Deliver the notification
    mNotificationManager.notify(NOTIFICATION_ID, builder.build());
}

}

//具有解构      var [一个,两个,三个] = foo

例如:对象分解

var o = {p:42,q:true};    var {p,q} = o;

console.log(p); // 42    console.log(q); //是

//分配新的变量名    var {p:foo,q:bar} = o;

console.log(foo); // 42    console.log(bar); //是

答案 3 :(得分:0)

MDN上有let语句的文档:https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

letvar类似,因为它限制了声明变量的范围。它允许你在if(){}块(或其他一些块)中声明一个变量,并使该变量只在该块内“可见”(JavaScript,到目前为止,具有函数作用域而不像大多数其他语言一样阻止作用域) 。所以let基本上是一个“解决”许多人有问题的东西。请注意,tihs是JavaScript 1.7的一项功能。

{Foo}上找不到任何内容。