รันไทม์ Rhino จะปิดบริการในวันที่ 31 มกราคม 2026 หรือหลังจากนั้น หากคุณมีสคริปต์ที่ใช้รันไทม์ Rhino อยู่แล้ว คุณต้องย้ายข้อมูลสคริปต์ไปยัง V8
โดยปกติแล้ว สิ่งที่ต้องทำก่อนที่จะเพิ่มไวยากรณ์และฟีเจอร์ของ V8 ลงในสคริปต์ก็คือการ เปิดใช้รันไทม์ V8 อย่างไรก็ตาม มีความไม่เข้ากันและ ข้อแตกต่างอื่นๆเล็กน้อยที่อาจทำให้สคริปต์ทำงานไม่สำเร็จหรือ ทำงานผิดปกติในรันไทม์ V8 เมื่อย้ายข้อมูลสคริปต์เพื่อใช้ V8 คุณต้องค้นหาปัญหาเหล่านี้ในโปรเจ็กต์สคริปต์และแก้ไขปัญหาที่พบ
ขั้นตอนการย้ายข้อมูลไปยัง V8
หากต้องการย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทำตามขั้นตอนต่อไปนี้
- เปิดใช้รันไทม์ V8
สำหรับสคริปต์ คุณสามารถตรวจสอบ
runtimeVersionได้โดยใช้ ไฟล์ Manifest สำหรับโปรเจ็กต์ Google Apps Script - ตรวจสอบความไม่เข้ากันต่อไปนี้อย่างละเอียด ดูสคริปต์เพื่อตรวจสอบว่ามีความไม่เข้ากันใดๆ หรือไม่ หากมีความไม่เข้ากันอย่างน้อย 1 รายการ ให้ปรับโค้ดสคริปต์เพื่อนำปัญหาออกหรือหลีกเลี่ยงปัญหา
- ตรวจสอบข้อแตกต่างอื่นๆ ต่อไปนี้อย่างละเอียด ดูสคริปต์เพื่อตรวจสอบว่าข้อแตกต่างที่ระบุไว้ส่งผลต่อลักษณะการทำงานของโค้ดหรือไม่ ปรับสคริปต์เพื่อแก้ไขลักษณะการทำงาน
- เมื่อแก้ไขความไม่เข้ากันหรือข้อแตกต่างอื่นๆ ที่พบแล้ว ให้เริ่มอัปเดตโค้ดเพื่อใช้ ไวยากรณ์และฟีเจอร์อื่นๆ ของ V8
- หลังจากปรับโค้ดเสร็จแล้ว ให้ทดสอบสคริปต์อย่างละเอียดเพื่อให้แน่ใจว่าสคริปต์ทำงานตามที่คาดไว้
- หากสคริปต์เป็นเว็บแอปหรือส่วนเสริมที่เผยแพร่แล้ว คุณต้อง สร้างเวอร์ชันใหม่ของสคริปต์ที่มีการปรับ V8 และชี้การทำให้ใช้งานได้ไปยังเวอร์ชันที่สร้างขึ้นใหม่ หากต้องการให้ผู้ใช้ใช้เวอร์ชัน V8 ได้ คุณต้องเผยแพร่สคริปต์อีกครั้งด้วยเวอร์ชันนี้
- หากใช้สคริปต์เป็นไลบรารี ให้สร้างการทำให้ใช้งานได้แบบเวอร์ชันใหม่ของสคริปต์ แจ้งให้สคริปต์และผู้ใช้ทั้งหมดที่ใช้ไลบรารีของคุณทราบเกี่ยวกับเวอร์ชันใหม่นี้ และแนะนำให้ผู้ใช้และสคริปต์อัปเดตเป็นเวอร์ชันที่เปิดใช้ V8 ตรวจสอบว่าเวอร์ชันเก่าที่ใช้ Rhino ของไลบรารีไม่ได้ใช้งานหรือเข้าถึงไม่ได้อีกต่อไป
- ตรวจสอบว่าไม่มีอินสแตนซ์ของสคริปต์ที่ยังคงทำงานในรันไทม์ Rhino เดิม ตรวจสอบว่าการทำให้ใช้งานได้ ทั้งหมดเชื่อมโยงกับเวอร์ชันที่ใช้ V8 เก็บการทำให้ใช้งานได้เก่า ตรวจสอบ เวอร์ชันทั้งหมดและลบเวอร์ชัน ที่ไม่ได้ใช้รันไทม์ V8
ความไม่เข้ากัน
รันไทม์ Apps Script เดิมที่ใช้ Rhino อนุญาตให้มีลักษณะการทำงานของ ECMAScript ที่ไม่ได้มาตรฐานหลายอย่าง เนื่องจาก V8 เป็นไปตามมาตรฐาน จึงไม่รองรับลักษณะการทำงานเหล่านี้หลังจากการย้ายข้อมูล การไม่แก้ไขปัญหาเหล่านี้จะทำให้เกิดข้อผิดพลาดหรือลักษณะการทำงานของสคริปต์ผิดปกติเมื่อเปิดใช้รันไทม์ V8
ส่วนต่อไปนี้จะอธิบายลักษณะการทำงานแต่ละอย่างและขั้นตอนที่คุณต้องดำเนินการเพื่อแก้ไขโค้ดสคริปต์ระหว่างการย้ายข้อมูลไปยัง V8
หลีกเลี่ยง for each(variable in object)
คำสั่ง
for each (variable in object)
ได้รับการเพิ่มลงใน JavaScript 1.6 และนำออกเพื่อใช้ for...of แทน
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้หลีกเลี่ยงการใช้ for each (variable in object)
คำสั่ง
แต่ให้ใช้ for (variable in object) แทน
// Rhino runtime var obj = {a: 1, b: 2, c: 3}; // Don't use 'for each' in V8 for each (var value in obj) { Logger.log("value = %s", value); } |
// V8 runtime var obj = {a: 1, b: 2, c: 3}; for (var key in obj) { // OK in V8 var value = obj[key]; Logger.log("value = %s", value); } |
หลีกเลี่ยง Date.prototype.getYear()
ในรันไทม์ Rhino เดิม
Date.prototype.getYear()
จะแสดงปีเป็นตัวเลข 2 หลักสำหรับปี 1900-1999 แต่จะแสดงปีเป็นตัวเลข 4 หลักสำหรับ
วันที่อื่นๆ ซึ่งเป็นลักษณะการทำงานใน JavaScript 1.2 และเวอร์ชันก่อนหน้า
ในรันไทม์ V8
Date.prototype.getYear()
จะแสดงปีลบด้วย 1900 แทนตามที่มาตรฐาน ECMAScript กำหนด
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ใช้
Date.prototype.getFullYear() เสมอ
ซึ่งจะแสดงปีเป็นตัวเลข 4 หลักไม่ว่าจะเป็นวันที่ใดก็ตาม
หลีกเลี่ยงการใช้คีย์เวิร์ดที่สงวนไว้เป็นชื่อ
ECMAScript ห้ามใช้คีย์เวิร์ดที่สงวนไว้บางคำ ในชื่อฟังก์ชันและตัวแปร รันไทม์ Rhino อนุญาตให้ใช้คำเหล่านี้ได้หลายคำ ดังนั้นหากโค้ดของคุณใช้คำเหล่านี้ คุณต้องเปลี่ยนชื่อฟังก์ชันหรือตัวแปร
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้หลีกเลี่ยงการตั้งชื่อตัวแปรหรือฟังก์ชันโดยใช้คีย์เวิร์ดที่สงวนไว้
ของ
คีย์เวิร์ดที่สงวนไว้
เปลี่ยนชื่อตัวแปรหรือฟังก์ชันเพื่อหลีกเลี่ยงการใช้ชื่อคีย์เวิร์ด การใช้คีย์เวิร์ดเป็นชื่อที่พบบ่อย ได้แก่ class, import และ export
ข้อยกเว้นอย่างหนึ่งคือออบเจ็กต์ลิเทอรัลได้รับอนุญาตให้ใช้คีย์เวิร์ดที่สงวนไว้ (ในรันไทม์ทั้งหมด)
function class() {} // Syntax error in V8. var obj = { class: 1 }; // Allowed.
หลีกเลี่ยงการกำหนดค่าใหม่ให้กับตัวแปร const
ในรันไทม์ Rhino เดิม คุณสามารถประกาศตัวแปรโดยใช้ const ซึ่งหมายความว่าค่าของสัญลักษณ์จะไม่เปลี่ยนแปลง และระบบจะละเว้นการกำหนดค่าในอนาคตให้กับสัญลักษณ์
ในรันไทม์ V8 ใหม่ คีย์เวิร์ด const เป็นไปตามมาตรฐาน และการกำหนดค่า
ให้กับตัวแปรที่ประกาศเป็น const จะทำให้เกิดข้อผิดพลาดรันไทม์
TypeError: Assignment to constant variable
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 อย่าพยายามกำหนดค่าใหม่ให้กับตัวแปร
const
// Rhino runtime const x = 1; x = 2; // No error console.log(x); // Outputs 1 |
// V8 runtime const x = 1; x = 2; // Throws TypeError console.log(x); // Never executed |
หลีกเลี่ยง XML ลิเทอรัลและออบเจ็กต์ XML
ส่วนขยาย ที่ไม่เป็นไปตามมาตรฐาน ของ ECMAScript นี้อนุญาตให้โปรเจ็กต์ Apps Script ใช้ไวยากรณ์ XML ได้โดยตรง
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้หลีกเลี่ยงการใช้ XML ลิเทอรัลโดยตรงหรือออบเจ็กต์ XML
แต่ให้ใช้ XmlService เพื่อ แยกวิเคราะห์ XML แทน
// V8 runtime var incompatibleXml1 = <container><item/></container>; // Don't use var incompatibleXml2 = new XML('<container><item/></container>'); // Don't use var xml3 = XmlService.parse('<container><item/></container>'); // OK |
อย่าสร้างฟังก์ชันตัววนซ้ำที่กำหนดเองโดยใช้ __iterator__
JavaScript 1.7 ได้เพิ่มฟีเจอร์ที่อนุญาตให้เพิ่มตัววนซ้ำที่กำหนดเองลงในคลาสใดก็ได้โดยการประกาศฟังก์ชัน __iterator__ ในต้นแบบของคลาสนั้น นอกจากนี้ยังมีการเพิ่มฟีเจอร์นี้ลงในรันไทม์ Rhino ของ Apps Script เพื่อความสะดวกของนักพัฒนาซอฟต์แวร์ อย่างไรก็ตาม ฟีเจอร์นี้ไม่เคยเป็นส่วนหนึ่งของ
มาตรฐาน ECMA-262
และถูกนำออกในเครื่องมือ JavaScript ที่เป็นไปตามมาตรฐาน ECMAScript สคริปต์ที่ใช้ V8 จะใช้การสร้างตัววนซ้ำนี้ไม่ได้
เมื่อย้ายสคริปต์ไปยัง V8 ให้หลีกเลี่ยงฟังก์ชัน __iterator__ เพื่อสร้างตัววนซ้ำที่กำหนดเอง แต่ให้ใช้
ตัววนซ้ำ ECMAScript 6 แทน
ลองพิจารณาการสร้างอาร์เรย์ต่อไปนี้
// Create a sample array var myArray = ['a', 'b', 'c']; // Add a property to the array myArray.foo = 'bar'; // The default behavior for an array is to return keys of all properties, // including 'foo'. Logger.log("Normal for...in loop:"); for (var item in myArray) { Logger.log(item); // Logs 0, 1, 2, foo } // To only log the array values with `for..in`, a custom iterator can be used. |
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีสร้างตัววนซ้ำในรันไทม์ Rhino และวิธีสร้างตัววนซ้ำทดแทนในรันไทม์ V8
// Rhino runtime custom iterator function ArrayIterator(array) { this.array = array; this.currentIndex = 0; } ArrayIterator.prototype.next = function() { if (this.currentIndex >= this.array.length) { throw StopIteration; } return "[" + this.currentIndex + "]=" + this.array[this.currentIndex++]; }; // Direct myArray to use the custom iterator myArray.__iterator__ = function() { return new ArrayIterator(this); } Logger.log("With custom Rhino iterator:"); for (var item in myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } |
// V8 runtime (ECMAScript 6) custom iterator myArray[Symbol.iterator] = function() { var currentIndex = 0; var array = this; return { next: function() { if (currentIndex < array.length) { return { value: "[${currentIndex}]=" + array[currentIndex++], done: false}; } else { return {done: true}; } } }; } Logger.log("With V8 custom iterator:"); // Must use for...of since // for...in doesn't expect an iterable. for (var item of myArray) { // Logs [0]=a, [1]=b, [2]=c Logger.log(item); } |
ในรันไทม์ V8 คุณต้องใช้ for...of เมื่อข้ามผ่านอาร์เรย์ที่มีตัววนซ้ำที่กำหนดเอง เนื่องจาก for..in ไม่คาดหวังว่าจะได้รับ Iterable
หลีกเลี่ยง Clause Catch แบบมีเงื่อนไข
รันไทม์ V8 ไม่รองรับ Clause Catch แบบมีเงื่อนไข catch..if เนื่องจากไม่เป็นไปตามมาตรฐาน
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ย้ายเงื่อนไข Catch ทั้งหมดไว้ใน เนื้อหา Catch:
// Rhino runtime try { doSomething(); } catch (e if e instanceof TypeError) { // Don't use // Handle exception } |
// V8 runtime try { doSomething(); } catch (e) { if (e instanceof TypeError) { // Handle exception } } |
หลีกเลี่ยงการใช้ Object.prototype.toSource()
JavaScript 1.3 มีเมธอด Object.prototype.toSource() ซึ่งไม่เคยเป็นส่วนหนึ่งของมาตรฐาน ECMAScript ใดๆ และไม่รองรับในรันไทม์ V8
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้นำการใช้ Object.prototype.toSource() ออกจากโค้ด
ข้อแตกต่างอื่นๆ
นอกเหนือจากความไม่เข้ากันที่กล่าวไว้ข้างต้นซึ่งอาจทำให้สคริปต์ทำงานไม่สำเร็จแล้ว ยังมีข้อแตกต่างอื่นๆ อีกเล็กน้อยที่อาจทำให้สคริปต์รันไทม์ V8 ทำงานผิดปกติหากไม่ได้รับการแก้ไข
ส่วนต่อไปนี้จะอธิบายวิธีอัปเดตโค้ดสคริปต์เพื่อหลีกเลี่ยงปัญหาที่ไม่คาดคิดเหล่านี้
ปรับการจัดรูปแบบวันที่และเวลาเฉพาะภาษา
เมธอด Date
toLocaleString(),
toLocaleDateString(),
และ toLocaleTimeString()
จะทำงานแตกต่างกันในรันไทม์ V8 เมื่อเทียบกับ Rhino
ใน Rhino รูปแบบเริ่มต้นคือ รูปแบบยาว และระบบจะละเว้นพารามิเตอร์ที่ส่งเข้ามา
ในรันไทม์ V8 รูปแบบเริ่มต้นคือ รูปแบบสั้น และระบบจะจัดการพารามิเตอร์
ที่ส่งเข้ามาตามมาตรฐาน ECMA (ดูรายละเอียดใน
toLocaleDateString()เอกสารประกอบ
)
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทดสอบและปรับการคาดการณ์ของโค้ด เกี่ยวกับเอาต์พุตของเมธอดวันที่และเวลาเฉพาะภาษา:
// Rhino runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "December 21, 2012" in Rhino console.log(event.toLocaleDateString()); // Also outputs "December 21, 2012", // ignoring the parameters passed in. console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); |
// V8 runtime var event = new Date( Date.UTC(2012, 11, 21, 12)); // Outputs "12/21/2012" in V8 console.log(event.toLocaleDateString()); // Outputs "21. Dezember 2012" console.log(event.toLocaleDateString( 'de-DE', { year: 'numeric', month: 'long', day: 'numeric' })); |
หลีกเลี่ยงการใช้ Error.fileName และ Error.lineNumber
ในรันไทม์ V8 ออบเจ็กต์ JavaScript มาตรฐาน
Error
ไม่รองรับ fileName หรือ lineNumber เป็นพารามิเตอร์ของตัวสร้าง
หรือพร็อพเพอร์ตี้ของออบเจ็กต์
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8
ให้นำการพึ่งพา Error.fileName และ Error.lineNumber ออก
อีกทางเลือกหนึ่งคือการใช้
Error.prototype.stack
สแต็กนี้ยังไม่เป็นไปตามมาตรฐาน แต่ V8 รองรับ รูปแบบของ Stack Trace ที่แพลตฟอร์มทั้ง 2 สร้างขึ้นจะแตกต่างกันเล็กน้อย ดังนี้
// Rhino runtime Error.prototype.stack // stack trace format at filename:92 (innerFunction) at filename:97 (outerFunction) |
// V8 runtime Error.prototype.stack // stack trace format Error: error message at innerFunction (filename:92:11) at outerFunction (filename:97:5) |
ปรับการจัดการออบเจ็กต์ Enum ที่แปลงเป็นสตริง
ในรันไทม์ Rhino เดิม การใช้เมธอด JavaScript
JSON.stringify()
กับออบเจ็กต์ Enum จะแสดงผล {} เท่านั้น
ใน V8 การใช้เมธอดเดียวกันกับออบเจ็กต์ Enum จะแสดงผลชื่อ Enum
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทดสอบและปรับการคาดการณ์ของโค้ด
เกี่ยวกับเอาต์พุตของ
JSON.stringify()
ในออบเจ็กต์ Enum:
// Rhino runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to {} |
// V8 runtime var enumName = JSON.stringify(Charts.ChartType.BUBBLE); // enumName evaluates to "BUBBLE" |
ปรับการจัดการพารามิเตอร์ที่ไม่ได้กำหนด
ในรันไทม์ Rhino เดิม การส่ง undefined ไปยังเมธอดเป็นพารามิเตอร์
จะส่งสตริง "undefined" ไปยังเมธอดนั้น
ใน V8 การส่ง undefined ไปยังเมธอดจะเทียบเท่ากับการส่ง null
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทดสอบและปรับการคาดการณ์ของโค้ด
เกี่ยวกับพารามิเตอร์undefined:
// Rhino runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has the string // "undefined" as its value. |
// V8 runtime SpreadsheetApp.getActiveRange() .setValue(undefined); // The active range now has no content, as // setValue(null) removes content from // ranges. |
ปรับการจัดการ this ทั่วโลก
รันไทม์ Rhino กำหนดบริบทพิเศษโดยนัยสำหรับสคริปต์ที่ใช้รันไทม์นี้
โค้ดสคริปต์จะทำงานในบริบทโดยนัยนี้ ซึ่งแตกต่างจาก this ทั่วโลกจริง ซึ่งหมายความว่าการอ้างอิง "global this" ในโค้ดจะประเมินเป็นบริบทพิเศษ ซึ่งมีเพียงโค้ดและตัวแปรที่กำหนดไว้ในสคริปต์ ระบบจะยกเว้นบริการในตัวของ Apps Script และออบเจ็กต์ ECMAScript จากการใช้ this นี้ สถานการณ์นี้คล้ายกับโครงสร้าง JavaScript ต่อไปนี้
// Rhino runtime // Apps Script built-in services defined here, in the actual global context. var SpreadsheetApp = { openById: function() { ... } getActive: function() { ... } // etc. }; function() { // Implicit special context; all your code goes here. If the global this // is referenced in your code, it only contains elements from this context. // Any global variables you defined. var x = 42; // Your script functions. function myFunction() { ... } // End of your code. }(); |
ใน V8 ระบบจะนำบริบทพิเศษโดยนัยออก ตัวแปรและฟังก์ชันทั่วโลกที่กำหนดไว้ในสคริปต์จะอยู่ในบริบททั่วโลก นอกเหนือจากบริการในตัวของ Apps Script และฟังก์ชันในตัวของ ECMAScript เช่น Math และ Date
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทดสอบและปรับการคาดการณ์ของโค้ด
เกี่ยวกับการใช้ this ในบริบททั่วโลก ในกรณีส่วนใหญ่ ข้อแตกต่างจะปรากฏให้เห็นก็ต่อเมื่อโค้ดตรวจสอบคีย์หรือชื่อพร็อพเพอร์ตี้ของออบเจ็กต์ this ทั่วโลกเท่านั้น
// Rhino runtime var myGlobal = 5; function myFunction() { // Only logs [myFunction, myGlobal]; console.log(Object.keys(this)); // Only logs [myFunction, myGlobal]; console.log( Object.getOwnPropertyNames(this)); } |
// V8 runtime var myGlobal = 5; function myFunction() { // Logs an array that includes the names // of Apps Script services // (CalendarApp, GmailApp, etc.) in // addition to myFunction and myGlobal. console.log(Object.keys(this)); // Logs an array that includes the same // values as above, and also includes // ECMAScript built-ins like Math, Date, // and Object. console.log( Object.getOwnPropertyNames(this)); } |
ปรับการจัดการ instanceof ในไลบรารี
การใช้ instanceof ในไลบรารีกับออบเจ็กต์ที่ส่งเป็นพารามิเตอร์ในฟังก์ชันจากโปรเจ็กต์อื่นอาจทำให้เกิดผลลัพธ์เชิงลบที่ไม่ถูกต้อง ในรันไทม์ V8 โปรเจ็กต์และไลบรารีจะทำงานในบริบทการดำเนินการที่แตกต่างกัน จึงมีตัวแปรทั่วโลกและสายโซ่ต้นแบบที่แตกต่างกัน
กรณีนี้จะเกิดขึ้นก็ต่อเมื่อไลบรารีใช้ instanceof กับออบเจ็กต์ที่ไม่ได้สร้างในโปรเจ็กต์ของคุณ การใช้ `instanceof` กับออบเจ็กต์ที่สร้างในโปรเจ็กต์ของคุณ ไม่ว่าจะอยู่ในสคริปต์เดียวกันหรือสคริปต์อื่นภายในโปรเจ็กต์ ควรทำงานตามที่คาดไว้
หากโปรเจ็กต์ที่ทำงานใน V8 ใช้สคริปต์ของคุณเป็นไลบรารี ให้ตรวจสอบว่า
สคริปต์ใช้ instanceof กับพารามิเตอร์ที่ส่งจากโปรเจ็กต์อื่นหรือไม่
ปรับการใช้ instanceof และใช้ทางเลือกอื่นที่เป็นไปได้ตาม Use Case ของคุณ
ทางเลือกหนึ่งสำหรับ a instanceof b คือการใช้เครื่องมือสร้างของ a ในกรณีที่คุณไม่จำเป็นต้องค้นหาสายโซ่ต้นแบบทั้งหมดและเพียงแค่ตรวจสอบเครื่องมือสร้าง การใช้งาน: a.constructor.name == "b"
ลองพิจารณาโปรเจ็กต์ A และโปรเจ็กต์ B โดยที่โปรเจ็กต์ A ใช้โปรเจ็กต์ B เป็นไลบรารี
//Rhino runtime //Project A function caller() { var date = new Date(); // Returns true return B.callee(date); } //Project B function callee(date) { // Returns true return(date instanceof Date); } |
//V8 runtime //Project A function caller() { var date = new Date(); // Returns false return B.callee(date); } //Project B function callee(date) { // Incorrectly returns false return(date instanceof Date); // Consider using return (date.constructor.name == // “Date”) instead. // return (date.constructor.name == “Date”) -> Returns // true } |
อีกทางเลือกหนึ่งคือการแนะนำฟังก์ชันที่ตรวจสอบ instanceof ในโปรเจ็กต์หลักและส่งฟังก์ชันนอกเหนือจากพารามิเตอร์อื่นๆ เมื่อเรียกใช้ฟังก์ชันไลบรารี จากนั้นจะใช้ฟังก์ชันที่ส่งเพื่อตรวจสอบ instanceof ภายในไลบรารีได้
//V8 runtime //Project A function caller() { var date = new Date(); // Returns True return B.callee(date, date => date instanceof Date); } //Project B function callee(date, checkInstanceOf) { // Returns True return checkInstanceOf(date); } |
ปรับการส่งทรัพยากรที่ไม่แชร์ไปยังไลบรารี
การส่งทรัพยากรที่ไม่แชร์จากสคริปต์หลักไปยังไลบรารีจะทำงานแตกต่างกันในรันไทม์ V8
ในรันไทม์ Rhino การส่งทรัพยากรที่ไม่แชร์จะใช้ไม่ได้ ไลบรารีจะใช้ทรัพยากรของตัวเองแทน
ในรันไทม์ V8 การส่งทรัพยากรที่ไม่แชร์ไปยังไลบรารีจะใช้ได้ ไลบรารีจะใช้ทรัพยากรที่ไม่แชร์ที่ส่งมา
อย่าส่งทรัพยากรที่ไม่แชร์เป็นพารามิเตอร์ฟังก์ชัน ให้ประกาศทรัพยากรที่ไม่แชร์ในสคริปต์เดียวกันกับที่ใช้ทรัพยากรเหล่านั้นเสมอ
ลองพิจารณาโปรเจ็กต์ A และโปรเจ็กต์ B โดยที่โปรเจ็กต์ A ใช้โปรเจ็กต์ B เป็นไลบรารี ในตัวอย่างนี้ PropertiesService เป็นทรัพยากรที่ไม่แชร์
// Rhino runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-B Logger.log(B.getScriptProperties( PropertiesService, 'project')); } |
// V8 runtime // Project A function testPassingNonSharedProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-A'); B.setScriptProperties(); // Prints: Project-A Logger.log(B.getScriptProperties( PropertiesService, 'project')); } |
คำแนะนำเกี่ยวกับ JDBC ในรันไทม์ V8
เราได้เพิ่มฟีเจอร์ใหม่ลงในบริการ JDBC ด้วยรันไทม์ V8
ใช้ executeBatch สำหรับการดำเนินการแบบกลุ่ม
ใช้การดำเนินการ executeBatch(params) เพื่อดำเนินการฐานข้อมูลแบบกลุ่ม
ตัวอย่างต่อไปนี้แสดงวิธีแทรกหลายแถวลงในฐานข้อมูลโดยใช้การจัดกลุ่ม
นี่คือรันไทม์ Rhino (วิธีเก่า)
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; for (var i = 0; i < params.length; i++) { stmt.setString(1, params[i][0]); stmt.setInt(2, params[i][1]); stmt.execute(); }
นี่คือรันไทม์ V8 (วิธีใหม่)
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.prepareStatement("INSERT INTO employees (name, age) VALUES (?, ?)"); var params = [["John Doe", 30], ["John Smith", 25]]; stmt.executeBatch(params);
ใช้ getRows เพื่อดึงข้อมูลชุดผลลัพธ์
ใช้ getRows(queryString) เพื่อดึงข้อมูลชุดผลลัพธ์ในการเรียกใช้ครั้งเดียว
queryString ประกอบด้วยการเรียกใช้เมธอด Getter ของ
JdbcResultSet ที่คั่นด้วยคอมมา เช่น "getString(1), getDouble('price'), getDate(3,
'UTC')". เมธอดที่รองรับ ได้แก่ เมธอด Getter ทั้งหมดที่รับผิดชอบในการอ่านข้อมูลคอลัมน์ เช่น getHoldability, getMetaData เป็นต้น ไม่รองรับ อาร์กิวเมนต์อาจเป็นดัชนีคอลัมน์จำนวนเต็ม (อิงตาม 1) หรือป้ายกำกับคอลัมน์สตริงที่อยู่ในเครื่องหมายคำพูดเดี่ยวหรือเครื่องหมายคำพูดคู่
ตัวอย่างต่อไปนี้แสดงวิธีดึงข้อมูลแถวจากชุดผลลัพธ์
นี่คือรันไทม์ Rhino (วิธีเก่า)
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); while (rs.next()) { Logger.log(rs.getString('name') + ", " + rs.getInt('age')); }
นี่คือรันไทม์ V8 (วิธีใหม่)
var conn = Jdbc.getCloudSqlConnection("jdbc:google:mysql://..."); var stmt = conn.createStatement(); var rs = stmt.executeQuery("SELECT name, age FROM employees"); var rows = rs.getRows("getString('name'), getInt('age')"); for (var i = 0; i < rows.length; i++) { Logger.log(rows[i][0] + ", " + rows[i][1]); }
อัปเดตสิทธิ์เข้าถึงสคริปต์แบบสแตนด์อโลน
สำหรับสคริปต์แบบสแตนด์อโลนที่ทำงานในรันไทม์ V8 คุณต้องให้สิทธิ์ดูสคริปต์แก่ผู้ใช้เป็นอย่างน้อยเพื่อให้ทริกเกอร์ของสคริปต์ทำงานได้อย่างถูกต้อง