หากคุณมีสคริปต์ที่ใช้รันไทม์ของ Rhino อยู่แล้วและต้องการใช้รันไทม์ของ Rhino ของไวยากรณ์และฟีเจอร์ V8 คุณต้องย้ายสคริปต์ไปยัง V8
สคริปต์ส่วนใหญ่ที่เขียนโดยใช้รันไทม์ของ Rhino สามารถทำงานโดยใช้รันไทม์ V8 ได้ โดยไม่ต้องปรับ ซึ่งมักเป็นเพียงข้อกำหนดเบื้องต้นในการเพิ่มไวยากรณ์ V8 และ ลงในสคริปต์คือ การเปิดใช้รันไทม์ V8
แต่มีกลุ่มตัวอย่าง ความเข้ากันไม่ได้ และความแตกต่างอื่นๆ ที่อาจส่งผลให้สคริปต์ ล้มเหลวหรือทำงานโดยไม่คาดคิดหลังจากเปิดใช้รันไทม์ V8 ขณะที่คุณย้ายข้อมูล สคริปต์ที่จะใช้ V8 คุณต้องค้นหาโปรเจ็กต์สคริปต์สำหรับปัญหาเหล่านี้และ แก้ไขทุกอย่างที่พบ
ขั้นตอนการย้ายข้อมูล V8
เมื่อต้องการย้ายสคริปต์ไปยัง V8 ให้ทำตามขั้นตอนต่อไปนี้
- เปิดใช้รันไทม์ V8 สำหรับสคริปต์
- ตรวจสอบความไม่เข้ากันอย่างละเอียด ที่ระบุไว้ด้านล่าง ตรวจสอบสคริปต์เพื่อดูว่ามีความเข้ากันไม่ได้หรือไม่ หากมีความเข้ากันไม่ได้อย่างน้อย 1 ข้อ ให้ปรับโค้ดสคริปต์เพื่อนำปัญหาออกหรือหลีกเลี่ยงปัญหา
- ตรวจสอบความแตกต่างอื่นๆ ที่ระบุไว้ด้านล่างอย่างละเอียด ตรวจสอบสคริปต์เพื่อดูว่าความแตกต่างที่แสดงนั้นส่งผลกระทบหรือไม่ ลักษณะการทำงานของโค้ด ปรับสคริปต์เพื่อแก้ไขลักษณะการทำงาน
- เมื่อแก้ไขความไม่เข้ากันได้หรือความแตกต่างอื่นๆ ที่พบแล้ว คุณสามารถเริ่มอัปเดตโค้ดเพื่อใช้ไวยากรณ์ V8 และฟีเจอร์อื่นๆ ได้ตามต้องการ
- หลังจากปรับเปลี่ยนโค้ดเสร็จแล้ว ให้ทดสอบสคริปต์ของคุณอย่างละเอียดเพื่อ ทำงานตามที่คาดไว้
- หากสคริปต์เป็นเว็บแอปหรือส่วนเสริมที่เผยแพร่แล้ว คุณต้อง สร้างเวอร์ชันใหม่ ของสคริปต์ได้ด้วยการปรับเปลี่ยน 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
หลีกเลี่ยงการกำหนดตัวแปร 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 ของ Google
ให้ใช้ 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 Iterators
ลองพิจารณาการสร้างอาร์เรย์ต่อไปนี้
// 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. |
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการสร้าง Iterator ใน รันไทม์ของ 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); } |
หลีกเลี่ยงการใช้วลี Catch แบบมีเงื่อนไข
รันไทม์ V8 ไม่รองรับcatch..if
ประโยคเงื่อไขของคำสั่ง catch เนื่องจากไม่เป็นไปตามมาตรฐาน
เมื่อย้ายข้อมูลสคริปต์ไปยัง V8 ให้ย้ายเงื่อนไขการจับข้อผิดพลาดภายในส่วนเนื้อหาของเงื่อนไขการจับข้อผิดพลาด
// 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
สแต็กนี้ไม่เป็นไปตามมาตรฐานเช่นกัน แต่รองรับทั้งใน Rhino และ V8
รูปแบบของสแต็กเทรซที่ทั้ง 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
ไปยัง Method เทียบเท่ากับการส่ง 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
ระดับบนสุดจริง ซึ่งหมายความว่าการอ้างอิงไปยัง "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
และใช้ตัวเลือกอื่นๆ ที่เป็นไปได้ตามการใช้งานของคุณ
ของ Google
ทางเลือกหนึ่งสำหรับ 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 คุณต้องให้ข้อมูลผู้ใช้อย่างน้อย สิทธิ์ดูสคริปต์เพื่อให้ทริกเกอร์ของสคริปต์ทำงานอย่างถูกต้อง