Rhino çalışma zamanını kullanan mevcut bir komut dosyanız varsa ve komut dosyasını V8'e taşımanız gerekir.
Rhino çalışma zamanı kullanılarak yazılan çoğu komut dosyası, V8 çalışma zamanı ile çalışabilir gerçekleşiyor. Bir komut dosyasına V8 söz dizimi ve özellikleri eklemenin tek ön koşulu genellikle V8 çalışma zamanını etkinleştirmektir.
Ancak V8 çalışma zamanını etkinleştirdikten sonra komut dosyasının başarısız olmasına veya beklenmedik şekilde davranmasına neden olabilecek küçük bir uyumsuzluk ve diğer farklılıklar vardır. Taşıma sırasında komut dosyası oluşturduktan sonra bu sorunları ve komut dosyası projesini düzeltin.
V8 taşıma prosedürü
Bir komut dosyasını V8'e taşımak için şu prosedürü uygulayın:
- V8 çalışma zamanını etkinleştirme tercih edebilirsiniz.
- Uyumsuzlukları dikkatlice inceleyin aşağıda listelenmiştir. Aşağıdakilerden herhangi birinin mevcut olup olmadığını belirlemek için komut dosyanızı inceleyin: mevcut uyumsuzluklar var. bir veya daha fazla uyumsuzluk varsa sorunu gidermek veya önlemek için komut dosyası kodunuzu ayarlayın.
- Aşağıda listelenen diğer farklılıkları dikkatlice inceleyin. Listelenen farklılıklardan herhangi birinin etkili olup olmadığını belirlemek için komut dosyanızı inceleyin. kodunuzun davranışını gösterir. Komut dosyanızı bu davranışı düzeltecek şekilde düzenleyin.
- Tespit edilen uyumsuzlukları veya diğer farklılıkları düzelttikten sonra, kodunuzu V8 söz dizimini ve diğer özellikleri istediğiniz gibi kullanacak şekilde güncellemeye başlayabilirsiniz.
- Kod ayarlamalarınızı tamamladıktan sonra, ve beklendiği gibi işlediğinden emin olmaktır.
- Komut dosyanız bir web uygulaması veya yayınlanmış eklenti ise yapman gereken yeni bir sürüm oluşturun komut dosyasının V8 düzenlemelerine sahip olmasını sağlayın. V8 sürümünü kullanıyorsanız komut dosyasını bu sürümle yeniden yayınlamanız gerekir.
Uyumsuzluklar
Rhino tabanlı orijinal Apps Komut Dosyası çalışma zamanı maalesef birçok standart dışı ECMAScript davranışları. V8 standartlara uygun olduğundan bu davranışlar taşıma işleminden sonra desteklenmez. Bu sorunların düzeltilmemesi V8 çalışma zamanı etkinleştirildiğinde hatalara veya bozuk komut dosyası davranışına neden olur.
Aşağıdaki bölümlerde bu davranışların her biri ve uygulamanız gereken adımlar açıklanmaktadır kullanarak V8'e geçiş sırasında komut dosyası kodunuzu düzeltin.
for each(variable in object)
kullanmaktan kaçının
İlgili içeriği oluşturmak için kullanılan
for each (variable in object)
ifadesi, JavaScript 1.6'ya eklendi ve for...of
lehine kaldırıldı.
Komut dosyanızı V8'e taşırken for each (variable in object)
kullanmaktan kaçının.
ifadeleri.
Bunun yerine for (variable in object)
işlevini kullanın:
// 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()
kullanmaktan kaçının
Orijinal Rhino çalışma zamanında
Date.prototype.getYear()
1900-1999 yılları için iki basamaklı yılları, diğer yıllar için ise dört basamaklı yılları döndürür
tarihlerine göre düzenlenmiştir.
V8 çalışma zamanında,
Date.prototype.getYear()
şunun yerine, yılı eksi 1900 çıkarıp döndürür
dahil edilir.
Komut dosyanızı V8'e taşırken her zaman
Date.prototype.getFullYear()
,
tarihi ne olursa olsun dört basamaklı bir yıl döndürür.
Ayrılmış anahtar kelimeleri ad olarak kullanmaktan kaçının
ECMAScript, bazı dokümanların ayırtılmış anahtar kelimeler kullanabilirsiniz. Rhino çalışma zamanı bu kelimelerin çoğuna izin verdi bu nedenle, kodunuz bunları kullanıyorsa işlevlerinizi veya değişkenlerinizi yeniden adlandırmanız gerekir.
Komut dosyanızı V8'e taşırken değişkeni veya işlevleri adlandırmaktan kaçının
ayırtılmış anahtar kelimeler bölümüne bakın.
Anahtar kelime adını kullanmaktan kaçınmak için değişkenleri veya işlevleri yeniden adlandırın. Yaygın kullanım şekilleri
class
, import
ve export
gibi anahtar kelimeler bulunuyor.
const
değişkenini yeniden atamaktan kaçının
Orijinal Rhino çalışma zamanında, son haline getirmek için const
kullanarak
sembolün değerinin hiçbir zaman değişmemesi ve
simgeleri göz ardı edilir.
Yeni V8 çalışma zamanında, const
anahtar kelimesi standart olarak uyumludur ve
const
olarak tanımlanan bir değişkene dönüştürmek,
TypeError: Assignment to constant variable
çalışma zamanı hatası.
Komut dosyanızı V8'e taşırken,
bir const
değişkeni görebilirsiniz:
// 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 |
Değişmez XML değerlerinden ve XML nesnesinden kaçının.
Bu standart olmayan uzantı yayınlamak, Apps Komut Dosyası projelerinin doğrudan XML söz dizimini kullanmasına olanak tanır.
Komut dosyanızı V8'e taşırken doğrudan XML değişmez değerlerini veya XML'yi kullanmaktan kaçının. nesne.
Bunun yerine, XML'i ayrıştırmak için XmlService'i kullanın:
// 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__
kullanarak özel iteratör işlevleri oluşturmayın
JavaScript 1.7, sınıfın prototipinde bir __iterator__
işlevi tanımlayarak herhangi bir sınıfa özel bir iteratör ekleme olanağı sağlayan bir özellik ekledi. Bu özellik, geliştiricilere kolaylık sağlamak amacıyla Apps Script'in Rhino çalışma zamanında da eklendi. Ancak,
bu özellik
ECMA-262 standardı
ve ECMAScript uyumlu JavaScript motorlarında kaldırılmıştır. V8 kullanan komut dosyaları bu iteratör yapısını kullanamaz.
Komut dosyanızı V8'e taşırken derlemek için __iterator__
işlevinden kaçının
özel iterasyonlar. Bunun yerine
ECMAScript 6 yinelemelerini kullanın.
Aşağıdaki dizi yapısını ele alalım:
// 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. |
Aşağıdaki kod örnekleri, Rhino çalışma zamanında bir iteratörün nasıl oluşturulabileceğini ve V8 çalışma zamanında bir değişim iteratörünün nasıl oluşturulabileceğini gösterir:
// 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); } |
Koşullu yakalama ifadeleri kullanmaktan kaçının
V8 çalışma zamanı, catch..if
koşullu yakalama deyimlerini desteklemez
birlikte kullanıldığında standartlarla uyumlu değildir.
Komut dosyanızı V8'e taşırken, catch koşullularını catch gövdesinin içine taşıyın:
// 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()
kullanmaktan kaçının
JavaScript 1.3, Object.prototype.toSource() bir ECMAScript standardının parçası olmayan eski yöntemler kullanır. V8 çalışma zamanında desteklenmez.
Komut dosyanızı V8'e taşırken, Object.prototype.toSource() kodunuzdan kaldırın.
Diğer farklılıklar
Komut dosyası hatalarına neden olabilecek yukarıdaki uyumsuzluklara ek olarak, düzeltilmezse beklenmedik V8'e neden olabilecek diğer birkaç farklılık çalışma zamanı komut dosyası davranışı.
Aşağıdaki bölümlerde, bu sorunlardan kaçınmak için komut dosyası kodunuzu nasıl güncelleyebileceğiniz açıklanmaktadır. beklenmedik sürprizler.
Yerel ayara özel tarih ve saat biçimlendirmesini ayarla
Date
yöntem toLocaleString()
,
toLocaleDateString()
,
ve toLocaleTimeString()
belirli bir
çok daha farklı sonuçlar veriyor.
Rhino'da varsayılan biçim long format ve yoksayılır.
V8 çalışma zamanında varsayılan biçim kısa biçim ve parametrelerdir.
ECMA standardına göre ele alınır (bkz.
toLocaleDateString()
belgeleri
bakın).
Kodunuzu V8'e taşırken yerel ayara özgü tarih ve saat yöntemlerinin çıkışıyla ilgili kodunuzun beklentilerini test edip düzenleyin:
// 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
ve Error.lineNumber
kullanmaktan kaçının
V8 zamanında, standart JavaScript
Error
nesne, fileName
veya lineNumber
parametresini kurucu parametreler olarak desteklemiyor
özellikleri olabilir.
Komut dosyanızı V8'e taşırken,
Error.fileName
ve Error.lineNumber
ile ilişkili tüm bağımlılıkları kaldırın.
Alternatif olarak,
Error.prototype.stack
.
Bu yığın da standart dışıdır ancak hem Rhino hem de V8'de desteklenir. İlgili içeriği oluşturmak için kullanılan
iki platform tarafından oluşturulan yığın izlemenin (stack trace) biçimi biraz farklıdır:
// 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) |
Dizeleştirilmiş enum nesnelerinin işlenmesini ayarlama
Orijinal Rhino çalışma zamanında JavaScript'i kullanarak
JSON.stringify()
yöntemi yalnızca {}
değerini döndürür.
V8'de, bir numaralandırma nesnesinde aynı yöntemin kullanılması enum adını geri alır.
Komut dosyanızı V8'e taşırken,
kodunuzun çıktıyla ilgili beklentilerini test etme ve ayarlama
JSON.stringify()
enum nesnelerinde:
// 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" |
Tanımlanmamış parametrelerin işlenmesini ayarlayın
Orijinal Rhino çalışma zamanında, undefined
parametresi bir yönteme parametre olarak iletiliyor
ile sonuçlandığı gibi, "undefined"
dizesinin bu yönteme iletilmesiyle sonuçlanmıştır.
V8'de, undefined
yönteminin yöntemlere aktarılması, null
değerinin iletilmesiyle eşdeğerdir.
Komut dosyanızı V8'e taşırken,
kodunuzun undefined
parametreleriyle ilgili beklentilerini test edin ve ayarlayın:
// 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. |
Global this
için işlenmeyi ayarlayın
Rhino çalışma zamanı, bunu kullanan komut dosyaları için örtülü özel bir bağlam tanımlar.
Komut dosyası kodu, gerçek global koddan farklı olarak, bu örtülü bağlamda çalışır.
this
Bu, "genel this
" referansları anlamına gelir koda eklemeli
yalnızca kodu ve değişkenleri içeren özel bağlamı değerlendirerek
komut dosyasında tanımlanmıştır. Yerleşik Apps Komut Dosyası hizmetleri ve ECMAScript nesneleri, this
'ün bu kullanımından hariç tutulur. Bu durum şuna benziyordu:
JavaScript yapısı:
// 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'de, örtülü özel bağlam kaldırılır. Genel değişkenler ve işlevler
yerel bağlama yerleştirilir ve
Apps Komut Dosyası hizmetleri ile Math
ve Date
gibi ECMAScript yerleşik entegrasyonları.
Komut dosyanızı V8'e taşırken kodunuzun beklentilerini test edin ve ayarlayın
this
kullanımı hakkında genel bilgi verdi. Çoğu durumda,
ve kodunuz yalnızca öğenin anahtarlarını veya özellik adlarını incelediğinde
genel this
nesnesi:
// 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)); } |
Kitaplıklarda instanceof
öğelerinin işlenmesini ayarlama
Başka bir projedeki işlevde parametre olarak iletilen bir nesnede kitaplıkta instanceof
kullanılması yanlış negatif sonuç verebilir. V8 çalışma zamanında
ve kitaplıkları farklı yürütme bağlamlarında çalıştırıldığı için
zincirleri mevcut.
Bunun yalnızca kitaplığınız projenizde oluşturulmayan bir nesnede instanceof
kullanıyorsa geçerli olduğunu unutmayın. Bu örneği, oluşturma sırasında oluşturulan bir nesnede
ister projenizde aynı isterse farklı bir komut dosyasıyla olsun,
beklendiği gibi çalışmalıdır.
V8 üzerinde çalışan bir proje komut dosyanızı kitaplık olarak kullanıyorsa
komut dosyası, başka bir projeden aktarılacak bir parametrede instanceof
kullanıyor. Ayarlayın:
instanceof
kullanımını ve kullanımınıza göre diğer uygun alternatifleri kullanmanızı öneririz.
destek kaydı oluşturun.
a instanceof b
için bir alternatif, a
oluşturucusunu
Bu durumlarda, prototip zincirinin tamamında arama yapmanız gerekmez ve
hazırlayan kullanıcıdır.
Kullanım: a.constructor.name == "b"
A Projesi'nin B Projesi'ni kitaplık olarak kullandığı A Projesi ile B Projesi'ni düşünün.
//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 } |
Diğer bir alternatif de ana projede instanceof
değerini kontrol eden ve bir kitaplık işlevi çağırırken diğer parametrelere ek olarak işlevi de iletmek için bir işlev eklemektir. İletilen işlev
ardından instanceof
kitaplığını kontrol etmek için kullanılabilir.
//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); } |
Paylaşılmayan kaynakların kitaplıklara iletimini ayarlama
Paylaşılmayan bir kaynağın ana komut dosyasından kitaplığa iletilmesi, V8 çalışma zamanında farklı şekilde çalışır.
Rhino çalışma zamanında paylaşılmayan bir kaynağın iletilmesi işe yaramaz. Kitaplık bunun yerine kendi kaynağını kullanır.
V8 çalışma zamanında, paylaşılmayan bir kaynağı kitaplığa aktarmak işe yarar. Kitaplık, iletilen paylaşılmayan kaynağı kullanır.
Paylaşılmayan kaynakları işlev parametreleri olarak iletmeyin. Paylaşılmayan kaynakları her zaman, onları kullanan aynı komut dosyasında bildirin.
A Projesi’nin kitaplık olarak kullanıldığı A ve B projelerini düşünün. Bu örnekte, PropertiesService
paylaşılmayan bir kaynaktır.
// 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')); } |
Bağımsız komut dosyalarına erişimi güncelleme
V8 çalışma zamanında çalışan bağımsız komut dosyaları için kullanıcılara en azından komut dosyası için görüntüleme erişimine sahip olması gerekir.