การเข้าถึงคุณสมบัติ JavaScript: เครื่องหมายจุดเทียบกับวงเล็บ?


394

นอกเหนือจากความจริงที่ชัดเจนว่ารูปแบบแรกสามารถใช้ตัวแปรและไม่ใช่แค่ตัวอักษรสตริงมีเหตุผลใดที่จะใช้อีกแบบหนึ่งและถ้าเป็นเช่นนั้นภายใต้กรณีใด

ในรหัส:

// Given:
var foo = {'bar': 'baz'};

// Then
var x = foo['bar'];

// vs. 
var x = foo.bar;

บริบท: ฉันได้เขียนโปรแกรมสร้างโค้ดที่สร้างนิพจน์เหล่านี้และฉันสงสัยว่าสิ่งใดจะเหมาะสมกว่า


3
เพียงเพื่อชิปในไม่ได้คำตอบไปที่คำถามเดิมของคุณ (ตั้งแต่คุณมีความอุดมสมบูรณ์ของคำอธิบายที่ดีเพื่อให้ห่างไกล) แต่ความเร็วฉลาดไม่มีความแตกต่างมูลค่าการกล่าวขวัญอย่างใดอย่างหนึ่ง: jsperf.com/dot-vs-square-brackets การทดสอบข้างต้นให้ผลกำไรเพียง 2% ที่ดีที่สุดสำหรับพวกเขาทั้งคู่นั่นคือคอและคอ
ไม่ทราบ


คำถาม / คำตอบนี้สามารถใช้ได้กับคีย์ UTF-8 ด้วย
Peter Krauss

คำตอบ:


422

(ที่มาจากที่นี่ )

สัญกรณ์วงเล็บเหลี่ยมอนุญาตให้ใช้อักขระที่ไม่สามารถใช้กับเครื่องหมายจุดได้

var foo = myForm.foo[]; // incorrect syntax
var foo = myForm["foo[]"]; // correct syntax

รวมถึงอักขระที่ไม่ใช่ ASCII (UTF-8) เช่นเดียวกับในmyForm["ダ"]( ตัวอย่างเพิ่มเติม )

ประการที่สองสัญกรณ์วงเล็บเหลี่ยมจะมีประโยชน์เมื่อจัดการกับชื่อคุณสมบัติที่แตกต่างกันไปตามวิธีที่คาดการณ์ได้:

for (var i = 0; i < 10; i++) {
  someFunction(myForm["myControlNumber" + i]);
}

Roundup:

  • เครื่องหมายดอทจะเร็วกว่าในการเขียนและอ่านได้ชัดเจนยิ่งขึ้น
  • เครื่องหมายวงเล็บเหลี่ยมช่วยให้สามารถเข้าถึงคุณสมบัติที่มีอักขระพิเศษและการเลือกคุณสมบัติโดยใช้ตัวแปร

อีกตัวอย่างหนึ่งของตัวละครที่ไม่สามารถนำมาใช้ด้วยจุดสัญกรณ์เป็นชื่อคุณสมบัติที่ตัวเองมีจุด

ยกตัวอย่างเช่นการตอบสนอง JSON bar.Bazอาจมีคุณสมบัติที่เรียกว่า

var foo = myResponse.bar.Baz; // incorrect syntax
var foo = myResponse["bar.Baz"]; // correct syntax

45
ตัวอย่างโค้ดและถ้อยคำของบทสรุปนั้นดูคุ้นเคยเป็นอย่างมาก dev-archive.net/articles/js-dot-notation
Quentin

61
ไม่จำเป็นต้องประดิษฐ์ล้ออีกครั้งใช่ไหม? อ้างถึงมันเป็นข้อมูลอ้างอิง
Aron Rotteveel

13
สัญกรณ์ดอทเร็วขึ้น (สำหรับฉันอย่างน้อย) ทดสอบเบราว์เซอร์ของคุณjsperf.com/dot-notation-vs-bracket-notation/2
เดฟเฉิน

4
ใน chrome 44 บนเครื่องหมายวงเล็บของเครื่องของฉันเร็วขึ้น
Austin France

2
@chenghuayang เมื่อคุณต้องการเข้าถึงคุณสมบัติของวัตถุที่มีการจัดเก็บคีย์ไว้ในตัวแปรคุณจะไม่สามารถใช้เครื่องหมายจุดได้
Abdul

104

เครื่องหมายวงเล็บช่วยให้คุณสามารถเข้าถึงคุณสมบัติตามชื่อที่เก็บไว้ในตัวแปร:

var obj = { "abc" : "hello" };
var x = "abc";
var y = obj[x];
console.log(y); //output - hello

obj.x จะไม่ทำงานในกรณีนี้


12

วิธีการทั่วไปสองวิธีในการเข้าถึงคุณสมบัติใน JavaScript คือใช้จุดและมีวงเล็บเหลี่ยม ทั้งสองvalue.x and value[x]เข้าถึงคุณสมบัติตามมูลค่า แต่ไม่จำเป็นต้องเป็นคุณสมบัติเดียวกัน ความแตกต่างคือวิธีการตีความ x เมื่อใช้จุดส่วนหลังจุดจะต้องเป็นชื่อตัวแปรที่ถูกต้องและตั้งชื่อคุณสมบัติโดยตรง เมื่อใช้วงเล็บเหลี่ยมนิพจน์ระหว่างวงเล็บปีกกาจะถูกประเมินเพื่อรับชื่อคุณสมบัติ โดยที่ value.x จะดึงคุณสมบัติของค่าชื่อ“ x” ค่า [x] พยายามประเมินนิพจน์ x และใช้ผลลัพธ์เป็นชื่อคุณสมบัติ

ดังนั้นถ้าคุณรู้ว่าทรัพย์สินที่คุณกำลังสนใจในการที่เรียกว่า“ความยาว” value.lengthคุณพูด หากคุณต้องการที่จะดึงคุณสมบัติที่มีชื่อตามค่าที่จัดขึ้นในตัวแปรที่คุณพูดi value[i]และเนื่องจากชื่อคุณสมบัติสามารถเป็นสตริงใด ๆ หากคุณต้องการเข้าถึงชื่อคุณสมบัติ“2”หรือคุณต้องใช้วงเล็บ:“John Doe” value[2] or value["John Doe"]นี่เป็นกรณีแม้ว่าคุณจะรู้ชื่อที่ถูกต้องของคุณสมบัติล่วงหน้าเนื่องจากไม่มี“2” nor “John Doe”ชื่อตัวแปรที่ถูกต้องและไม่สามารถเข้าถึงได้ผ่านเครื่องหมายจุด

ในกรณีของอาร์เรย์

องค์ประกอบในอาร์เรย์จะถูกเก็บไว้ในคุณสมบัติ เนื่องจากชื่อของคุณสมบัติเหล่านี้เป็นตัวเลขและบ่อยครั้งที่เราต้องได้รับชื่อจากตัวแปรเราจึงต้องใช้ไวยากรณ์ของวงเล็บเหลี่ยมเพื่อเข้าถึง คุณสมบัติความยาวของอาเรย์บอกเราว่ามีองค์ประกอบจำนวนเท่าใด ชื่อคุณสมบัตินี้เป็นชื่อตัวแปรที่ถูกต้องและเรารู้ว่าชื่อของมันล่วงหน้าเพื่อที่จะหาความยาวของอาร์เรย์คุณมักจะเขียนเพราะเห็นว่าเป็นเรื่องง่ายที่จะเขียนได้น้อยกว่าarray.lengtharray["length"]


คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับ array.length ได้ไหม? คุณบอกว่าคุณสมบัติที่เข้าถึงด้วยเครื่องหมายจุดไม่ได้รับการประเมินดังนั้นในกรณีของ array.length จะไม่ให้สตริง "ความยาว" แก่เราแทนที่จะเป็นค่าที่ประเมินในกรณีนี้จำนวนของรายการในอาร์เรย์? The elements in an array are stored in propertiesนี่คือสิ่งที่ทำให้ฉันสับสน คุณหมายถึงอะไรโดยเก็บไว้ในคุณสมบัติ? คุณสมบัติคืออะไร ในอาร์เรย์ความเข้าใจของฉันเป็นเพียงค่าที่ไม่มีคุณสมบัติ ถ้ามันถูกเก็บไว้ในคุณสมบัติทำไมมันไม่ได้เป็นproperty: value/ อาเรย์เชื่อมโยง?
Limpuls

คำตอบนี้มีประโยชน์อย่างยิ่งเพราะจะอธิบายความแตกต่างระหว่างสองสัญลักษณ์
chessweb

11

เครื่องหมายดอทไม่ทำงานกับคำหลักบางคำ (เช่นnewและclass) ใน internet explorer 8

ฉันมีรหัสนี้:

//app.users is a hash
app.users.new = {
  // some code
}

และสิ่งนี้ทริกเกอร์ "indentifier ที่คาดหวัง" ที่น่ากลัว (อย่างน้อยใน IE8 บน windows xp ฉันไม่ได้ลองสภาพแวดล้อมอื่น ๆ ) การแก้ไขที่ง่ายสำหรับการที่จะสลับไปที่สัญกรณ์วงเล็บ:

app.users['new'] = {
  // some code
}

คำตอบที่เป็นประโยชน์ ขอบคุณ.
Ilyas karim

ใช้งานได้กับ chrome 2019 res.cloudinary.com/rootworld/image/upload/v1567651133/js.png
Phani Rithvij

8

ระวังขณะใช้สัญลักษณ์เหล่านี้: สำหรับตัวอย่าง ถ้าเราต้องการเข้าถึงฟังก์ชั่นที่มีอยู่ในหน้าต่างหลักของหน้าต่าง ใน IE:

window['parent']['func']

ไม่เท่ากับ

window.['parent.func']

เราอาจใช้:

window['parent']['func'] 

หรือ

window.parent.func 

เพื่อเข้าถึง


6

โดยทั่วไปแล้วพวกเขาทำงานเดียวกัน
อย่างไรก็ตามเครื่องหมายวงเล็บจะเปิดโอกาสให้คุณทำสิ่งที่คุณไม่สามารถทำได้ด้วยเครื่องหมายจุดเช่น

var x = elem["foo[]"]; // can't do elem.foo[];

สิ่งนี้สามารถขยายไปยังคุณสมบัติใด ๆ ที่มีอักขระพิเศษ


5

คุณต้องใช้วงเล็บถ้าชื่อคุณสมบัติมีอักขระพิเศษ:

var foo = {
    "Hello, world!": true,
}
foo["Hello, world!"] = false;

นอกจากนั้นฉันคิดว่ามันเป็นแค่เรื่องของรสนิยม IMHO เครื่องหมายดอทจะสั้นกว่าและทำให้เห็นได้ชัดว่ามันเป็นคุณสมบัติแทนที่จะเป็นองค์ประกอบอาร์เรย์ (แม้ว่าแน่นอนว่า JavaScript ไม่มีอาร์เรย์เชื่อมโยงอยู่แล้ว)


3

เครื่องหมายวงเล็บเหลี่ยมสามารถใช้ตัวแปรได้ดังนั้นจึงมีประโยชน์ในสองกรณีที่เครื่องหมายดอทจะไม่ทำงาน:

1) เมื่อชื่อคุณสมบัติถูกกำหนดแบบไดนามิก (เมื่อไม่ทราบชื่อที่แน่นอนจนกระทั่งรันไทม์)

2) เมื่อใช้ for..in loop เพื่อผ่านคุณสมบัติทั้งหมดของวัตถุ

แหล่งที่มา: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects


3

คุณต้องใช้เครื่องหมายวงเล็บเหลี่ยมเมื่อ -

  1. ชื่อคุณสมบัติคือหมายเลข

    var ob = {
      1: 'One',
      7 : 'Seven'
    }
    ob.7  // SyntaxError
    ob[7] // "Seven"
  2. ชื่อคุณสมบัติมีอักขระพิเศษ

    var ob = {
      'This is one': 1,
      'This is seven': 7,
    }  
    ob.'This is one'  // SyntaxError
    ob['This is one'] // 1
  3. ชื่อคุณสมบัติถูกกำหนดให้กับตัวแปรและคุณต้องการเข้าถึงค่าคุณสมบัติโดยตัวแปรนี้

    var ob = {
      'One': 1,
      'Seven': 7,
    }
    
    var _Seven = 'Seven';
    ob._Seven  // undefined
    ob[_Seven] // 7

1

กรณีที่[]สัญกรณ์เป็นประโยชน์:

หากวัตถุของคุณเป็นแบบไดนามิกและอาจมีค่าสุ่มในคีย์เช่นnumberและ[]หรืออักขระพิเศษอื่น ๆ เช่น -

var a = { 1 : 3 };

ตอนนี้ถ้าคุณพยายามที่จะเข้าถึงเหมือนa.1มันจะผ่านข้อผิดพลาดเพราะมันคาดหวังว่าสตริงที่นั่น


1

เครื่องหมายดอทจะดีกว่าเสมอ หากคุณกำลังใช้ IDE หรือตัวแก้ไขข้อความ "ชาญฉลาด" มันจะแสดงชื่อที่ไม่ได้กำหนดจากวัตถุนั้น ใช้สัญกรณ์เครื่องหมายวงเล็บเมื่อคุณมีชื่อที่มีเครื่องหมายขีดคั่นหรือสิ่งที่คล้ายกันไม่ถูกต้อง และถ้าชื่อถูกเก็บไว้ในตัวแปร


และยังมีสถานการณ์ที่ไม่อนุญาตให้ใช้เครื่องหมายวงเล็บในทุกกรณีแม้ว่าคุณจะไม่มีเครื่องหมายขีดคั่นก็ตาม ตัวอย่างเช่นคุณสามารถเขียนแต่ไม่Math.sqrt(25) Math['sqrt'](25)
นาย Lister

0

ขอเพิ่มกรณีการใช้เครื่องหมายสัญกรณ์สแควร์ หากคุณต้องการเข้าถึงคุณสมบัติพูดx-proxyในวัตถุ-จะถูกตีความอย่างผิด ๆ กรณีของพวกเขาคือบางกรณีเช่นช่องว่างจุด ฯลฯ ซึ่งการทำงานของจุดจะไม่ช่วยคุณ นอกจากนี้หากคุณมีคีย์ในตัวแปรดังนั้นวิธีเดียวในการเข้าถึงค่าของคีย์ในวัตถุคือโดยเครื่องหมายวงเล็บ หวังว่าคุณจะได้รับบริบทเพิ่มเติม


0

ตัวอย่างที่สัญกรณ์จุดล้มเหลว

json = { 
   "value:":4,
   'help"':2,
   "hello'":32,
   "data+":2,
   "😎":'😴',
   "a[]":[ 
      2,
      2
   ]
};

// correct
console.log(json['value:']);
console.log(json['help"']);
console.log(json["help\""]);
console.log(json['hello\'']);
console.log(json["hello'"]);
console.log(json["data+"]);
console.log(json["😎"]);
console.log(json["a[]"]);

// wrong
console.log(json.value:);
console.log(json.help");
console.log(json.hello');
console.log(json.data+);
console.log(json.😎);
console.log(json.a[]);

ชื่อคุณสมบัติไม่ควรรบกวนกฎไวยากรณ์ของ javascript เพื่อให้คุณสามารถเข้าถึงได้ json.property_name

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.