การย้ายข้อมูลสคริปต์ไปยังรันไทม์ V8

หากมีสคริปต์ที่ใช้รันไทม์ของ Rhino และต้องการใช้ไวยากรณ์และฟีเจอร์ V8 คุณต้องย้ายสคริปต์ไปยัง V8

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

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

ขั้นตอนการย้ายข้อมูล V8

หากต้องการย้ายข้อมูลสคริปต์ไปยัง V8 ให้ทำตามขั้นตอนต่อไปนี้

  1. เปิดใช้รันไทม์ V8 สำหรับสคริปต์
  2. โปรดตรวจสอบรายการที่ใช้ร่วมกัน ตามรายการด้านล่างอย่างละเอียด ตรวจสอบสคริปต์เพื่อดูว่าพบความไม่เข้ากันบ้างไหม หากมีความไม่เข้ากันอย่างน้อย 1 รายการ ให้ปรับโค้ดสคริปต์เพื่อลบหรือหลีกเลี่ยงปัญหา
  3. ตรวจสอบความแตกต่างอื่นๆ ในรายการด้านล่างอย่างละเอียด ตรวจสอบสคริปต์เพื่อดูว่าความแตกต่างใดๆ ที่ระบุไว้ส่งผลกระทบต่อการทำงานของโค้ดหรือไม่ ปรับสคริปต์เพื่อแก้ไขลักษณะการทำงาน
  4. เมื่อแก้ไขความไม่เข้ากันหรือความแตกต่างอื่นๆ ที่ค้นพบแล้ว คุณจะเริ่มอัปเดตโค้ดเพื่อใช้ไวยากรณ์ V8 และฟีเจอร์อื่นๆ ได้ตามต้องการ
  5. หลังจากปรับโค้ดเสร็จแล้ว ให้ทดสอบสคริปต์อย่างละเอียดเพื่อตรวจสอบว่าทำงานตามที่คาดไว้
  6. หากสคริปต์เป็นเว็บแอปหรือส่วนเสริมที่เผยแพร่ คุณต้องสร้างสคริปต์เวอร์ชันใหม่ที่มีการปรับเปลี่ยน 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 ไม่อนุญาตให้ใช้คีย์เวิร์ดที่สงวนไว้บางคำในชื่อฟังก์ชันและตัวแปร รันไทม์แรดอนุญาตให้ใช้คำเหล่านี้หลายคำ ดังนั้นหากโค้ดของคุณใช้คำเหล่านี้ คุณต้องเปลี่ยนชื่อฟังก์ชันหรือตัวแปร

เมื่อย้ายสคริปต์ไปยัง 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 ได้เพิ่มฟีเจอร์เพื่อให้เพิ่มตัวซ้ำที่กำหนดเองลงใน CSS ใดก็ได้โดยการประกาศฟังก์ชัน __iterator__ ในต้นแบบของคลาสนั้น และยังมีการเพิ่มฟีเจอร์นี้ลงในรันไทม์ Rhino ของ Apps Script เพื่ออำนวยความสะดวกสำหรับนักพัฒนาซอฟต์แวร์ด้วย อย่างไรก็ตาม ฟีเจอร์นี้ไม่เคยเป็นส่วนหนึ่งของมาตรฐาน ECMA-262 และถูกนำออกไปในเครื่องมือ JavaScript ที่เป็นไปตามข้อกำหนดของ ECMAScript สคริปต์ที่ใช้ V8 ไม่สามารถใช้การสร้างตัวซ้ำนี้ได้

เมื่อย้ายสคริปต์ไปยัง V8 ให้หลีกเลี่ยงฟังก์ชัน __iterator__ เพื่อสร้างตัววนซ้ำที่กำหนดเอง แต่ให้ใช้ ECMAScript 6 Iterator แทน

ลองพิจารณาการสร้างอาร์เรย์ต่อไปนี้

// 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);
}
      

หลีกเลี่ยงการใช้วลีคำสั่ง catch แบบมีเงื่อนไข

รันไทม์ V8 ไม่รองรับอนุประโยค catch..if ที่มีเงื่อนไขเนื่องจากไม่เป็นไปตามข้อกำหนดมาตรฐาน

เมื่อย้ายสคริปต์ไปยัง 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() ออกจากโค้ด

ความแตกต่างอื่นๆ

นอกเหนือจากความไม่เข้ากันข้างต้นซึ่งอาจทำให้สคริปต์ทำงานไม่สำเร็จแล้ว ยังมีข้อแตกต่างอีก 2-3 ข้อที่หากไม่แก้ไข อาจทำให้เกิดลักษณะการทำงานของสคริปต์รันไทม์ V8 ที่ไม่คาดคิด

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

ปรับการจัดรูปแบบวันที่และเวลาของภาษา

เมธอด Date toLocaleString(), toLocaleDateString() และ toLocaleTimeString() ทำงานได้ แตกต่างกันในรันไทม์ V8 เมื่อเทียบกับ 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 ให้นำทรัพยากร Dependency ของ Error.fileName และ Error.lineNumber ออก

อีกวิธีหนึ่งคือการใช้ Error.prototype.stack กองนี้ไม่ใช่แบบมาตรฐาน แต่รองรับทั้งใน Rhino และ V8 รูปแบบของสแต็กเทรซที่ทั้งสองแพลตฟอร์มสร้างขึ้นจะแตกต่างกันเล็กน้อย ดังนี้

// 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 ที่เป็นสากลจริง ซึ่งหมายความว่าการอ้างอิงไปยัง "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 โปรเจ็กต์และไลบรารีของโปรเจ็กต์จะทำงานในบริบทของการดำเนินการที่ต่างกัน จึงทำให้มี globals และเชนต้นแบบที่แตกต่างกัน

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

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

อีกทางเลือกหนึ่งสำหรับ 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'));
}

//Project B function setScriptProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-B'); } function getScriptProperties( propertiesService, key) { return propertiesService.getScriptProperties() .getProperty(key); }

// V8 runtime
// Project A
function testPassingNonSharedProperties() {
  PropertiesService.getScriptProperties()
      .setProperty('project', 'Project-A');
  B.setScriptProperties();
  // Prints: Project-A
  Logger.log(B.getScriptProperties(
      PropertiesService, 'project'));
}

// Project B function setProperties() { PropertiesService.getScriptProperties() .setProperty('project', 'Project-B'); } function getScriptProperties( propertiesService, key) { return propertiesService.getScriptProperties() .getProperty(key); }

อัปเดตสิทธิ์เข้าถึงสคริปต์แบบสแตนด์อโลน

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