โดยรันไทม์ Rhino จะปิดบริการในวันที่ 31 มกราคม 2026 หรือหลังจากนั้น หากมีสคริปต์ที่ใช้รันไทม์ Rhino อยู่แล้ว คุณต้องย้ายข้อมูลสคริปต์ไปยัง V8
โดยปกติแล้ว ข้อกำหนดเบื้องต้นเพียงอย่างเดียวในการเพิ่มไวยากรณ์และฟีเจอร์ V8 ลงในสคริปต์คือการเปิดใช้รันไทม์ V8 อย่างไรก็ตาม มีชุดความไม่เข้ากัน และความแตกต่างอื่นๆ เล็กน้อยที่อาจทำให้สคริปต์ ทำงานล้มเหลวหรือทำงานอย่างไม่คาดคิดในรันไทม์ V8 เมื่อย้ายข้อมูล สคริปต์ไปใช้ V8 คุณต้องค้นหาปัญหาเหล่านี้ในโปรเจ็กต์สคริปต์และ แก้ไขปัญหาที่พบ
ขั้นตอนการย้ายข้อมูล V8
หากต้องการย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทำตามขั้นตอนต่อไปนี้
- เปิดใช้รันไทม์ V8
สำหรับสคริปต์ คุณตรวจสอบ
runtimeVersion
ได้โดยใช้ไฟล์ Manifest สำหรับโปรเจ็กต์ Apps Script - โปรดอ่านความไม่เข้ากันต่อไปนี้อย่างละเอียด ตรวจสอบสคริปต์เพื่อดูว่ามีปัญหาความไม่เข้ากันหรือไม่ หากมีปัญหาความไม่เข้ากันอย่างน้อย 1 รายการ ให้ปรับโค้ดสคริปต์เพื่อนำปัญหาออกหรือหลีกเลี่ยงปัญหา
- โปรดอ่านความแตกต่างอื่นๆ ต่อไปนี้อย่างละเอียด ตรวจสอบสคริปต์เพื่อดูว่าความแตกต่างที่ระบุไว้ส่งผลต่อลักษณะการทำงานของโค้ดหรือไม่ ปรับสคริปต์เพื่อแก้ไขลักษณะการทำงาน
- เมื่อแก้ไขความไม่เข้ากันหรือความแตกต่างอื่นๆ ที่พบแล้ว คุณจะเริ่มอัปเดตรหัสเพื่อใช้ไวยากรณ์ V8 และฟีเจอร์อื่นๆ ได้
- หลังจากปรับโค้ดเสร็จแล้ว ให้ทดสอบสคริปต์อย่างละเอียดเพื่อให้แน่ใจว่าสคริปต์ทำงานได้ตามที่คาดไว้
- หากสคริปต์เป็นเว็บแอปหรือส่วนเสริมที่เผยแพร่ คุณต้อง สร้างเวอร์ชันใหม่ ของสคริปต์ที่มีการปรับ V8 และชี้การติดตั้งใช้งานไปยังเวอร์ชันที่สร้างขึ้นใหม่ หากต้องการให้ผู้ใช้ใช้เวอร์ชัน V8 ได้ คุณต้อง เผยแพร่สคริปต์อีกครั้งด้วยเวอร์ชันนี้
- หากใช้สคริปต์เป็นไลบรารี ให้สร้างการติดตั้งใช้งานแบบเวอร์ชันใหม่ของ สคริปต์ แจ้งเวอร์ชันใหม่นี้ไปยังสคริปต์และผู้ใช้ทั้งหมดที่ ใช้ไลบรารีของคุณ พร้อมแนะนำให้ผู้ใช้อัปเดตเป็นเวอร์ชันที่เปิดใช้ V8 ตรวจสอบว่าเวอร์ชันเก่าที่ใช้ Rhino ของไลบรารีไม่ได้ ใช้งานหรือเข้าถึงได้อีกต่อไป
- ตรวจสอบว่าไม่มีอินสแตนซ์ของสคริปต์ที่ยังทำงานในรันไทม์ Rhino รุ่นเดิม ตรวจสอบว่าการติดตั้งใช้งานทั้งหมด เชื่อมโยงกับเวอร์ชันที่อยู่ใน V8 เก็บการติดตั้งใช้งานเก่า ตรวจสอบเวอร์ชันทั้งหมดและ ลบเวอร์ชันที่ไม่ได้ใช้ V8 Runtime
ความไม่เข้ากัน
น่าเสียดายที่รันไทม์ของ 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
หลีกเลี่ยงการกำหนดตัวแปร 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 ไม่รองรับประโยค 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() ออกจากโค้ด
ความแตกต่างอื่นๆ
นอกเหนือจากความไม่เข้ากันที่กล่าวมาข้างต้นซึ่งอาจทำให้สคริปต์ล้มเหลวแล้ว ยังมี ความแตกต่างอื่นๆ อีก 2-3 อย่างที่หากไม่แก้ไขอาจส่งผลให้เกิดลักษณะการทำงานของสคริปต์รันไทม์ 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()
ในออบเจ็กต์การแจงนับจะแสดงผล {}
เท่านั้น
ใน 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
กับออบเจ็กต์
ที่ไม่ได้สร้างในโปรเจ็กต์ การใช้ฟังก์ชันนี้กับออบเจ็กต์ที่สร้างขึ้นในโปรเจ็กต์ ไม่ว่าจะอยู่ในสคริปต์เดียวกันหรือสคริปต์อื่นภายในโปรเจ็กต์ ควรทำงานได้ตามที่คาดไว้
หากโปรเจ็กต์ที่ทำงานใน 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')); } |
อัปเดตสิทธิ์เข้าถึงสคริปต์แบบสแตนด์อโลน
สำหรับสคริปต์แบบสแตนด์อโลนที่ทำงานในรันไทม์ V8 คุณต้องให้สิทธิ์เข้าถึงสคริปต์แก่ผู้ใช้ในระดับดูเป็นอย่างน้อยเพื่อให้ทริกเกอร์ของสคริปต์ทำงานได้อย่างถูกต้อง