Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

Working with objects

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

ในบทนี้จะอธิบายวิธีการใช้อ็อบเจกต์, คุณสมบัติ, ฟังก์ชัน, และเมธอด รวมถึงวิธีการสร้างอ็อบเจกต์ของคุณเอง

อ็อบเจกต์เบื้องต้น

อ็อบเจกต์ต่างๆในจาวาสคริปต์, ก็เหมือนกับภาษาโปรแกรมแบบอื่นๆ ที่สามารถนำไปเปรียบเทียบได้กับวัตถุต่างๆในชีวิตจริง แนวคิดของอ็อบเจกต์ในจาวาสคริปต์ สามารถเข้าใจได้ด้วยวัตถุที่จับต้องได้ในชีวิตจริง

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

อ็อบเจกต์และคุณสมบัติ

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

objectName.propertyName

ก็เหมือนกับตัวแปรในจาวาสคริปต์ทุกตัว ชื่ออ็อบเจกต์ (ตัวแปรตัวหนึ่ง) และชื่อคุณสมบัติ แตกต่างกันตามตัวอักษรใหญ่เล็ก โดยคุณสามารถกำหนดคุณสมบัติด้วยการระบุค่าให้มัน เช่นในตัวอย่าง, เป็นการสร้างอ็อบเจกต์ myCar ที่มีคุณสมบัติชื่อ make, model, และ year ดังนี้:

var myCar = new Object();
myCar.make = "Ford";
myCar.model = "Mustang";
myCar.year = 1969;

คุณสมบัติของอ็อบเจกต์ในจาวาสคริปต์ยังสามารถเข้าถึงได้ด้วยการใช้รูปแบบวงเล็บเหลี่ยม ในบางครั้งเราเรียกอ็อบเจกต์ว่า อาร์เรย์แบบอิงชื่อ (associative array) เนื่องจากแต่ละคุณสมบัติจะมีค่าสตริงที่สามารถใช้เพื่อเข้าถึงตัวมันได้ ดังนั้น คุณจึงสามารถเข้าถึงคุณสมบัติต่างๆของอ็อบเจกต์ myCar ได้ตามตัวอย่างต่อไปนี้:

myCar["make"] = "Ford";
myCar["model"] = "Mustang";
myCar["year"] = 1969;

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

var myObj = new Object(),
    str = "myString",
    rand = Math.random(),
    obj = new Object();

myObj.type              = "Dot syntax";
myObj["date created"]   = "String with space";
myObj[str]              = "String value";
myObj[rand]             = "Random Number";
myObj[obj]              = "Object";
myObj[""]               = "Even an empty string";

console.log(myObj);

คุณสามารถเข้าถึงคุณสมบัติโดยใช้ค่าสตริงในตัวแปรได้ ดังนี้:

var propertyName = "make";
myCar[propertyName] = "Ford";

propertyName = "model";
myCar[propertyName] = "Mustang";

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

function showProps(obj, objName) {
  var result = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
        result += objName + "." + i + " = " + obj[i] + "\n";
    }
  }
  return result;
}

ดังนั้น, ถ้าเรียกฟังก์ชัน showProps(myCar, "myCar") จะได้ค่าดังนี้:

myCar.make = Ford
myCar.model = Mustang
myCar.year = 1969

ทุกสิ่งคืออ็อบเจกต์

ในจาวาสคริปต์ เกือบทุกสิ่งเป็นอ็อบเจกต์ โดยค่าข้อมูลพื้นฐานทั้งหมดยกเว้น null และ undefined ถือเป็นอ็อบเจกต์ ซึ่งสามารถกำหนดคุณสมบัติ (บางประเภทไม่สามารถกำหนดได้ถาวร) และมีคุณลักษณะทั้งหมดของอ็อบเจกต์

การแจกแจงคุณสมบัติของอ๊อบเจกต์

เริ่มจาก ECMAScript 5, มีสามวิธีที่จะแสดง/สำรวจ คุณสมบัติต่างๆของอ๊อบเจกต์:

  • ลูป for...in
    วิธีนี้จะได้คุณสมบัติที่แจกแจงได้ทั้งหมดของอ็อบเจกต์ รวมทั้งจากโปรโตไทป์ด้วย
  • ใช้เมธอด Object.keys(o)
    วิธีนี้จะคืนอาร์เรย์ของชื่อคุณสมบัติที่แจกแจงได้ทั้งหมด ของอ็อบเจกต์ o เอง (ไม่รวมที่มาจากโปรโตไทป์) 
  • ใช้เมธอด Object.getOwnPropertyNames(o)
    วิธีนี้จะคืนอาร์เรย์ของชื่อคุณสมบัติทั้งหมดของอ็อบเจกต์ o เอง (ทั้งแจกแจงได้และไม่ได้)

ใน ECMAScript 5, ยังไม่มีวิธีเฉพาะที่จะแสดงคุณสมบัติทั้งหมดของอ็อบเจกต์ แต่ก็สามารถทำได้ด้วยฟังก์ชันต่อไปนี้:

function listAllProperties(o){     
	var objectToInspect;     
	var result = [];
	
	for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){  
		result = result.concat(Object.getOwnPropertyNames(objectToInspect));  
	}
	
	return result; 
}

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

การสร้างอ็อบเจกต์ใหม่

จาวาสคริปต์มีอ็อบเจกต์พื้นฐานให้ใช้หลายแบบ และคุณสามารถสร้างอ็อบเจกต์เองเพิ่มได้ ในจาวาสคริปต์ 1.2 หรือใหม่กว่า, คุณสามารถสร้างอ็อบเจกต์ด้วยตัวสร้างอ็อบเจกต์ หรืออีกวิธีคือ สร้างฟังก์ชัน constructor และสร้างอ็อบเจกต์ใหม่ด้วยฟังก์ชันนี้กับตัวดำเนินการ new

การใช้ตัวสร้างอ็อบเจกต์

นอกจากการสร้างอ็อบเจกต์ด้วยฟังก์ชัน constructor แล้ว, คุณสามารถสร้างอ็อบเจกต์ด้วยตัวสร้างอ็อบเจกต์ ซึ่งการใช้ตัวสร้างอ็อบเจกต์นี้บางครั้งเรียกว่า การสร้างอ็อบเจกต์แบบใช้ค่าข้อมูล โดยตัวสร้างอ็อบเจกต์ (Object initializer) จะสอดคล้องกับความหมายที่ใช้ในภาษา C++

รูปแบบการสร้างอ็อบเจกต์ด้วยตัวสร้างอ็อบเจกต์ เป็นดังนี้:

var obj = { property_1:   value_1,   // property_# may be an identifier...
            2:            value_2,   // or a number...
            // ...,
            "property n": value_n }; // or a string

เมื่อ obj คือชื่อของอ็อบเจกต์ใหม่ แต่ละ property_i คือชื่อตัวแปร (เป็นได้ทั้งชื่อ, ตัวเลข, หรือค่าข้อมูลสตริง) และแต่ละ value_i คือนืพจน์ที่กำหนดค่าให้ property_i ทั้งนี้การกำหนด obj และการกำหนดค่า (=) เป็นแค่ทางเลือกเท่านั้น ซึ่งถ้าคุณไม่จำเป็นต้องอ้างถึงอ็อบเจกต์นี้ที่ไหนอีก คุณก็ไม่จำเป็นต้องกำหนดต่าให้ตัวแปร obj (จำไว้ว่า คุณอาจจำเป็นต้องห่อค่าข้อมูลอ็อบเจกต์ในวงเล็บ ถ้าอ็อบเจกต์อยู่ตรงตำแหน่งที่ควรจะเป็นคำสั่ง เพราะจะทำให้จาวาสคริปต์ไม่สับสนระหว่างค่าข้อมูลกับบล็อกคำสั่ง)

ถ้าอ็อบเจกต์หนึ่งถูกสร้างขึ้นด้วยตัวสร้างอ็อบเจกต์ในขั้นนอกสุดของสคริปต์, จาวาสคริปต์จะกำหนดค่าให้อ็อบเจกต์นี้ใหม่ ทุกครั้งที่มีการประมวลผลนิพจน์ที่มีตัวสร้างอ็อบเจกต์นี้อยู่ ขยายความได้ว่า, ตัวสร้างค่า (initializer) ที่ถูกใช้ในฟังก์ชันใด จะถูกสร้างขึ้นใหม่ทุกครั้งที่ฟังก์ชันนั้นถูกเรียกใช้งาน

คำสั่งต่อไปนี้สร้างอ็อบเจกต์ และกำหนดค่าให้ตัวแปร x ถ้านิพจน์ cond เป็นจริงเท่านั้น:

if (cond) var x = {hi: "there"};

ตัวอย่างต่อไปนี้จะสร้าง myHonda ที่มีสามคุณสมบัติ ซึ่งคุณสมบัติ engine ก็เป็นอ็อบเจกต์และมีคุณสมบัติของตัวเองด้วย

var myHonda = {color: "red", wheels: 4, engine: {cylinders: 4, size: 2.2}};

คุณสามารถใช้ตัวสร้างอ็อบเจกต์กับการสร้างอาร์เรย์ได้ ดูเพิ่มเติมที่ array literals

ในจาวาสคริปต์ 1.1 หรือก่อนหน้านั้น, คุณไม่สามารถใช้ตัวสร้างอ็อบเจกต์ชนิดต่างๆได้ คุณสามารถสร้างอ็อบเจกต์ได้จากฟังก์ชัน constructor หรือใช้ฟังก์ชันที่มากับอ็อบเจกต์บางชนิดเท่านั้น ดูเพิ่มเติมที่ Using a constructor function

การใช้ฟังก์ชัน constructor

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

  1. สร้างชนิดของอ็อบเจกต์ขึ้นมาใหม่โดยการเขียนฟังก์ชัน constructor โดยมีข้อกำหนดที่เคร่งครัดแต่มีเหตุผลคือ ควรใช้อักษรตัวใหญ่นำหน้าชื่อ
  2. สร้างตัวแปรอ็อบเจกต์ด้วยคำสั่ง new

การสร้างชนิดอ็อบเจกต์ทำได้โดย สร้างฟังก์ชันสำหรับชนิดอ็อบเจกต์ใหม่ที่ระบุ ชื่อ, คุณสมบัติ, และเมธอด ตัวอย่างเช่น, สมมุติว่าคุณค้องการสร้างชนิดอ็อบเจกต์ของรถยนต์ และต้องการเรียกอ็อบเจกต์ชนิดนี้ว่า Car ที่มีคุณสมบัติ make, model และ year คุณก็ควรเขียนโค้ดตามฟังก์ชันต่อไปนี้:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

ให้สังเกตุการใช้ this เพื่อกำหนดค่าให้คุณสมบัติของอ็อบเจกต์ จากค่าที่ส่งเข้าฟังก์ชัน

จากนี้ไป คุณก็สามารถสร้างอ็อบเจกต์ชื่อ mycar ได้ดังนี้:

var mycar = new Car("Eagle", "Talon TSi", 1993);

คำสั่งนี้สร้าง mycar และกำหนดค่าให้คุณสมบัติต่างๆ ดังนั้นค่าของ mycar.make ก็คือสตริง "Eagle", mycar.year คือเลข 1993 และอื่นๆ

คุณสามารถสร้างอ็อบเจกต์ Car ได้หลายตัว โดยใช้คำสั่ง new ดังตัวอย่าง,

var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);

อ็อบเจกต์สามารถมีคุณสมบัติที่เป็นอ็อบเจกต์อีกตัวได้ ตัวอย่างเช่น, คุณสร้างชนิดอ็อบเจกต์ใหม่ชื่อ Person ดังนี้:

function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

และสร้างอ็อบเจกต์ชนิด Person ขึ้นใหม่สองตัวดังนี้:

var rand = new Person("Rand McKinnon", 33, "M");
var ken = new Person("Ken Jones", 39, "M");

จากนั้น, คุณสามารถแก้ไขชนิดอ็อบเจกต์ Car โดยเพิ่ม คุณสมบัติ owner ซึ่งรับอ็อบเจกต์ชนิด Person ได้ดังนี้:

function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
}

และนำมาสร้างอ็อบเจกต์ใหม่ โดยใช้โค้ดดังนี้:

var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
var car2 = new Car("Nissan", "300ZX", 1992, ken);

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

car2.owner.name

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

car1.color = "black";

โดยเพิ่มคุณสมบัติ color ให้ car1 และกำหนดค่าเป็น "black" อย่างไรก็ตาม, วิธีนี้ไม่ส่งผลกับอ็อบเจกต์ Car ตัวอื่นๆ ซึ่งวิธีที่จะเพิ่มคุณสมบัติใหม่ให้อ็อบเจกต์ที่มีชนิดเดียวกันทั้งหมดคือ คุณต้องเพิ่มคุณสมบัติใหม่นี้ในตอนประกาศชนิดอ็อบเจกต์ Car ในฟังก์ชัน constructor เท่านั้น

การใช้เมธอด Object.create

อ็อบเจกต์ยังสามารถสร้างได้ด้วยการใช้เมธอด Object.create ซึ่งมีประโยชน์มาก เพราะให้คุณเลือกโปรโตไทป์ของอ็อบเจกต์ที่คุณต้องการสร้างได้ โดยไม่ต้องสร้างฟังก์ชัน constructor ดูรายละเอียดเพิ่มของเมธอดและการใช้งานได้ที่ Object.create method

การสืบทอด

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

ดัชนีคุณสมบัติของอ็อบเจกต์

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

ข้อจำกัดนี้ใช้เมื่อคุณสร้างอ็อบเจกต์และคุณสมบัติด้วยฟังก์ชัน constructor (ที่เราได้ทำมากับชนิดอ็อบเจกต์ Car) และเมื่อคุณสร้างคุณสมบัติแต่ละตัวโดยตรง (เช่น myCar.color = "red") ถ้าในตอนแรกคุณสร้างคุณสมบัติอ็อบเจกต์ด้วยเลขดัชนี เช่น myCar[5] = "25 mpg" คุณก็สามารถอ้างถึงคุณสมบัตินี้ได้ด้วย myCar[5] เท่านั้น

ข้อยกเว้นของกฏเกณฑ์นี้คือ อ็อบเจกต์ที่ได้จาก HTML เช่น อาร์เรย์ของฟอร์ม ซึ่งคุณสามารถอ้างถึงอ็อบเจกต์ในอาร์เรย์นี้ด้วยเลขดัชนี (ตามตำแหน่งที่ปรากฏในเอกสาร) หรือด้วยชื่อ (ถ้ามี) โดยตัวอย่าง เช่น ถ้า <FORM> ตัวที่สองในเอกสาร HTML มีค่า NAME เป็น "myForm", คุณสามารถอ้างถึงฟอร์มนี้ด้วย document.forms[1] หรือ document.forms["myForm"] หรือ document.myForm

การสร้างคุณสมบัติให้กับชนิดอ็อบเจกต์

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

Car.prototype.color = null;
car1.color = "black";

ดูข้อมูลเพิ่มเติมเรื่อง prototype property ของอ็อบเจกต์ Function ได้ที่ JavaScript Reference

การสร้างเมธอด

เมธอด คือฟังก์ชันที่ผูกเข้ากับอ็อบเจกต์ หรือพูดง่ายๆเมธอดก็คือ คุณสมบัติหนึ่งของอ็อบเจกต์ที่เป็นฟังก์ชัน ซึ่งสร้างได้ด้วยวิธีการสร้างฟังก์ชันทั่วไป ยกเวันว่าต้องกำหนดให้เป็นคุณสมบัติหนึ่งของอ็อบเจกต์ ดังตัวอย่าง:

objectName.methodname = function_name;

var myObj = {
  myMethod: function(params) {
    // ...do something
  }
};

เมื่อ objectName คืออ็อบเจกต์ที่มีอยู่แล้ว, methodname คือชื่อที่ตั้งให้เมธอด, และ function_name คือชื่อของฟังก์ชัน

คุณสามารถเรียกใช้เมธอดในอ็อบเจกต์ได้ดังนี้:

object.methodname(params);

คุณสามารถสร้างเมธอดให้กับอ็อบเจกต์ชนิดใดก็ได้ โดยสร้างไว้ในฟังก์ชัน constructor ตัวอย่างเช่น, คุณสามารถสร้างฟังก์ชันที่จะปรับรูปแบบและแสดงค่าคุณสมบัติของอ็อบเจกต์ Car ได้ดังนี้:

function displayCar() {
  var result = "A Beautiful " + this.year + " " + this.make
    + " " + this.model;
  pretty_print(result);
}

เมื่อ pretty_print คือฟังก์ชันที่แสดงเส้นบรรทัดและข้อความ ให้สังเกตุการใช้ this เพื่ออ้างถึงตัวอ็อบเจกต์ที่เป็นเจ้าของฟังก์ชันนี้

คุณสามารถทำให้ฟังก์ชันนี้เป็นเมธอดของ Car โดยเพิ่มคำสั่งนี้:

this.displayCar = displayCar;

เข้าไปในฟังก์ชัน constructor โดยจะได้โค้ดที่สมบูรณ์แบบนี้

function Car(make, model, year, owner) {
  this.make = make;
  this.model = model;
  this.year = year;
  this.owner = owner;
  this.displayCar = displayCar;
}

โดยคุณสามารถเรียกใช้เมธอด displayCar ได้จากทุกอ็อบเจกต์ Car ดังนี้:

car1.displayCar();
car2.displayCar();

ซึ่งจะได้ผลดังแสดงในรูปต่อไปนี้

Image:obja.gif

รูป 7.1: แสดงผลจากเมธอด

การใช้ this เพื่ออ้างถึงอ็อบเจ็กต์

จาวาสคริปต์มีคำพิเศษคำหนึ่ง คือ this, ซึ่งคุณสามารถใช้ในเมธอด เพื่ออ้างถึงอ็อบเจกต์ปัจจุบัน ตัวอย่างเช่น, สมมุติว่าคุณมีฟังก์ชันหนึ่งชื่อ validate ใช้ตรวจสอบคุณสมบัติ value ของอ็อบเจกต์ โดยรับค่าอ็อบเจกต์, ค่าสูง, และค่าต่ำ ดังนี้:

function validate(obj, lowval, hival) {
  if ((obj.value < lowval) || (obj.value > hival))
    alert("Invalid Value!");
}

และคุณเรียกใช้ validate ที่เหตุการณ์ onchange ของแต่ละฟิลด์ในฟอร์ม โดยส่งค่า this แทนฟิลด์ ตามตัวอย่างต่อไปนี้:

<input type="text" name="age" size="3"
  onChange="validate(this, 18, 99)">

โดยทั่วไปแล้ว, this อ้างถึงอ็อบเจกต์ที่เป็นผู้เรียกใช้เมธอด

เมื่อใช้ร่วมกับคุณสมบัติ form, this สามารถใช้อ้างถึงอ็อบเจกต์แม่ที่เป็นฟอร์มได้ ในตัวอย่างต่อไป, ฟอร์ม myForm ประกอบด้วยอ็อบเจกต์ Text และปุ่มกด เมื่อผู้ใช้คลิ๊กที่ปุ่ม, ค่าของอ็อบเจกต์ Text จะถูกกำหนดให้เป็นชื่อฟอร์ม โดยเหตุการณ์ onclick จะใช้ this.form เพื่ออ้างถึงฟอร์ม myForm

<form name="myForm">
<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
<p><input name="button1" type="button" value="Show Form Name"
     onclick="this.form.text1.value = this.form.name">
</p>
</form>

การสร้าง getter และ setter

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

JavaScript 1.8.1 note

ตั้งแต่จาวาสคริปต์ 1.8.1, setter ไม่ถูกเรียกใช้อีก เมื่อมีการกำหนดค่าคุณสมบัติในตัวสร้างอ็อบเจกต์ หรือตัวสร้างอาร์เรย์

ในการใช้งาน JS shell ต่อไปนี้ แสดงให้เห็นว่า getter และ setter ทำงานได้อย่างไรกับอ็อบเจกต์ที่สร้างขึ้นเอง ซึ่ง JS shell ก็คือแอปพลิเคชันที่ยอมให้นักพัฒนาทดสอบโค้ดจาวาสคริปต์ในแบบ batch หรือแบบ interactive ได้ โดยใน Firefox คุณสามารถเรียกใช้ JS shell ด้วยการกด Ctrl+Shift+K

js> var o = {a: 7, get b() {return this.a + 1;}, set c(x) {this.a = x / 2}};
[object Object]
js> o.a;
7
js> o.b;
8
js> o.c = 50;
js> o.a;
25

โดยคุณสมบัติของ o คือ:

  • o.a — ตัวเลข
  • o.b — getter ที่คืนค่า o.a บวก 1
  • o.c — setter ที่กำหนดค่าให้ o.a เป็นครึ่งหนึ่งของค่าที่ให้กับ o.c

กรุณาจำไว้ว่า ชื่อของฟังก์ชัน getter และ setter ที่ถูกสร้างในค่าข้อมูลอ็อบเจกต์ด้วย "[gs]et property()" (ไม่เหมือนกับ __define[GS]etter__) ไม่ใช่ชื่อของ getter เองแม้ว่ารูปแบบ [gs]et propertyName(){ } อาจทำให้เข้าใจผิดไปได้ โดยวิธีการตั้งชื่อฟังก์ชันของ getter หรือ setter ที่ใช้รูปแบบ "[gs]et property()" นั้น ให้ใช้คำสั่ง Object.defineProperty (หรือใช้ Object.prototype.__defineGetter__ ในแบบดั้งเดิม) กับฟังก์ชันที่ตั้งชื่อไว้แล้ว

ใน JS shell ต่อไปนี้ แสดงให้เห็นวิธีการใช้ getter และ setter ชยายโปรโตไทป์ของ Date โดยเพิ่มคุณสมบัติ year เข้าไปกับทุกอ็อบเจกต์ที่สร้างด้วยคลาส Date พื้นฐาน โดยนำเมธอด getFullYear และ setFullYear ที่มีอยู่แล้วในคลาส Date มาใช้ใน getter และ setter ของคุณสมบัติ year

โดยคำสั่งต่อไปนี้ จะสร้าง getter และ setter ของคุณสมบัติ year:

js> var d = Date.prototype;
js> Object.defineProperty(d, "year", {
    get: function() {return this.getFullYear() },
    set: function(y) { this.setFullYear(y) }
});

และคำสั่งต่อไปนี้ เรียกใช้ getter และ setter ในอ็อบเจกต์ Date:

js> var now = new Date;
js> print(now.year);
2000
js> now.year = 2001;
987617605170
js> print(now);
Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001

รูปแบบที่ไม่ใช้แล้ว

ในอดีต, จาวาสคริปต์รองรับรูปแบบการสร้าง getter และ setter หลายแบบ ซึ่งไม่มีแบบไหนเลยที่รองรับโดยตัวแปลภาษาจาวาสคริปต์ตัวอื่น และการสนับสนุนก็ถูกยกเลิกในเวอร์ชันใหม่ๆของจาวาสคริปต์ ดูรายละเอียดเพิ่มเติมเกี่ยวกับรูปแบบที่ถูกยกเลิกและวิธีการปรับปรุงโค้ดเพื่อรองรับการยกเลิกนี้ ที่ this dissection of the removed syntaxes

สรุป

ตามหลัก, getter และ setter สามารถเป็นได้ทั้ง

  • การสร้างด้วย object initializers, หรือ
  • เพิ่มเติมทีหลังไปที่อ็อบเจกต์ตอนไหนก็ได้ ด้วยเมธอดเพิ่ม getter หรือ setter

เมื่อสร้าง getter และ setter ด้วย object initializers สิ่งที่คุณต้องทำคือเพิ่มคำหน้าเมธอด getter ด้วย get และหน้า setter ด้วย set และที่แน่นอนคือ เมธอด getter ต้องไม่รับค่าตัวแปรเข้า ในขณะที่เมธอด setter รับค่าตัวแปรเข้าตัวเดียว (ค่าใหม่ที่ใช้) ตัวอย่างเช่น:

var o = {
  a: 7,
  get b() { return this.a + 1; },
  set c(x) { this.a = x / 2; }
};

ฟังก์ชัน getter และ setter สามารถเพิ่มไปที่อ็อบเจกต์ตอนไหนก็ได้หลังจากที่สร้างแล้วโดยใช้เมธอด Object.defineProperties ซึ่งตัวแปรรับเข้าตัวแรกของเมธอดคือ อ็อบเจกต์ที่คุณต้องการสร้าง getter หรือ setter, ตัวแปรรับเข้าตัวที่สองคือ อ็อบเจกต์ที่มีชื่อคุณสมบัติเป็นชื่อของ getter หรือ setter, และค่าคุณสมบัติเป็นอ็อบเจกต์ที่เป็นฟังก์ชัน getter หรือ setter โดยตัวอย่างต่อไปนี้แสดงการสร้าง getter และ setter ชุดเดียวกับตัวอย่างที่แล้ว:

var o = { a:0 }

Object.defineProperties(o, {
    "b": { get: function () { return this.a + 1; } },
    "c": { set: function (x) { this.a = x / 2; } }
});

o.c = 10 // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.b) // Runs the getter, which yields a + 1 or 6

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

ก่อนหน้า Firefox 3.0, getter และ setter ไม่รองรับกับส่วนประกอบ DOM โดยในเวอร์ชันที่เก่ากว่าจะไม่แจ้งเตือนข้อผิดพลาด ถ้าต้องการให้เกิดข้อผิดพลาด, มีวิธีแก้ไขเฉพาะหน้าคือ ให้เปลี่ยนโปรโตไทป์ของ HTMLElement (HTMLElement.prototype.__define[SG]etter__)และส่งข้อผิดพลาดออกมา

ด้วย Firefox 3.0, การสร้าง getter และ setter กับคุณสมบัติที่สร้างแล้วจะเกิดข้อผิดพลาดขึ้น โดยต้องลบคุณสมบัตินั้นก่อน ซึ่งทำไม่ได้ใน Firefox เวอร์ชันที่เก่ากว่า

ดูเพิ่มเติมที่

การลบคุณสมบัติ

คุณสามารถลบคุณสมบัติที่ไม่มีการสืบทอดด้วยตัวดำเนินการ delete โดยโค้ดต่อไปนี้แสดงการลบคุณสมบัติ

//Creates a new object, myobj, with two properties, a and b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;

//Removes the a property, leaving myobj with only the b property.
delete myobj.a;
console.log ("a" in myobj) // yields "false"

คุณก็สามารถใช้ delete ลบตัวแปรส่วนกลางที่ไม่ได้ใช้คำสั่ง var ตอนประกาศใช้:

g = 17;
delete g;

ดูข้อมูลเพิ่มเติมที่ delete

See also

Document Tags and Contributors

 Contributors to this page: jigs12, taveek, Zarazi
 Last updated by: jigs12,