javascript
了解React Native中的不同JavaScript环境
by Khoa Pham
通過Khoa Pham
了解React Native中的不同JavaScript環(huán)境 (Get to know different JavaScript environments in React Native)
React Native can be very easy to get started with, and then at some point problems occur and we need to dive deep into it.
React Native可能很容易上手 ,然后在某些時(shí)候出現(xiàn)問題,我們需要深入研究它。
The other day we had a strange bug that was only occurring in production build, and in iOS only. A long backtrace in the app revealed that it was due to Date constructor failure.
前幾天,我們遇到了一個(gè)奇怪的錯(cuò)誤,該錯(cuò)誤僅在生產(chǎn)版本中發(fā)生,并且僅在iOS中發(fā)生。 應(yīng)用程序中的長時(shí)間回溯顯示這是由于Date構(gòu)造函數(shù)故障引起的。
const date = new Date("2019-01-18 12:00:00")This returns the correct Date object in debug mode, but yields Invalid Date in release. What’s special about Date constructor? Here I’m using react native 0.57.5 and no Date libraries.
這會(huì)在調(diào)試模式下返回正確的Date對(duì)象,但在發(fā)行版中會(huì)產(chǎn)生Invalid Date 。 Date構(gòu)造函數(shù)有何特別之處? 在這里,我使用的是react native 0.57.5,并且沒有Date庫。
日期構(gòu)造器 (Date constructor)
The best resource for learning Javascript is via Mozilla web docs, and entering Date:
學(xué)習(xí)Javascript的最佳資源是通過Mozilla Web文檔,然后輸入Date :
Creates a JavaScript Date instance that represents a single moment in time. Date objects use a Unix Time Stamp, an integer value that is the number of milliseconds since 1 January 1970 UTC.
創(chuàng)建一個(gè)表示單個(gè)時(shí)刻JavaScript Date實(shí)例。 Date對(duì)象使用Unix時(shí)間戳記 ,它是一個(gè)整數(shù)值,它是自1970年1月1日UTC以來的毫秒數(shù)。
Pay attention to how Date can be constructed by dateString:
注意如何用dateString構(gòu)造Date:
dateStringString value representing a date. The string should be in a format recognized by the Date.parse() method (IETF-compliant RFC 2822 timestamps and also a version of ISO8601).
dateString表示日期的字符串值。 該字符串應(yīng)采用Date.parse()方法可識(shí)別的格式( 符合IETF的RFC 2822時(shí)間戳以及ISO8601的版本 )。
So Date constructor uses static method Date.parse under the hood. This has very specific requirement about the format of date string that it supports
所以Date構(gòu)造Date.parse在Date.parse使用靜態(tài)方法Date.parse 。 這對(duì)它支持的日期字符串的格式有非常具體的要求
The standard string representation of a date time string is a simplification of the ISO 8601 calendar date extended format (see Date Time String Format section in the ECMAScript specification for more details). For example, "2011-10-10" (date-only form), "2011-10-10T14:48:00" (date-time form), or "2011-10-10T14:48:00.000+09:00" (date-time form with milliseconds and time zone) can be passed and will be parsed. When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as local time.
日期時(shí)間字符串的標(biāo)準(zhǔn)字符串表示形式是ISO 8601日歷日期擴(kuò)展格式的簡化形式(有關(guān)更多詳細(xì)信息,請(qǐng)參見ECMAScript規(guī)范中的“ 日期時(shí)間字符串格式”部分)。 例如, "2011-10-10" (僅日期格式), "2011-10-10T14:48:00" (日期時(shí)間格式)或"2011-10-10T14:48:00.000+09:00" (具有毫秒和時(shí)區(qū)的日期時(shí)間格式)可以傳遞并進(jìn)行解析。 缺少時(shí)區(qū)偏移時(shí),僅日期格式將解釋為UTC時(shí)間,而日期時(shí)間格式將解釋為本地時(shí)間。
The ECMAScript specification states: If the String does not conform to the standard format the function may fall back to any implementation–specific heuristics or implementation–specific parsing algorithm. Unrecognizable strings or dates containing illegal element values in ISO formatted strings shall cause Date.parse() to return NaN.
ECMAScript規(guī)范指出:如果String不符合標(biāo)準(zhǔn)格式,則該函數(shù)可能會(huì)退回到任何特定于實(shí)現(xiàn)的試探法或特定于實(shí)現(xiàn)的解析算法。 ISO格式的字符串中無法識(shí)別的字符串或包含非法元素值的日期將導(dǎo)致Date.parse()返回NaN 。
The reason that we get Invalid Date in iOS must be because the code was run in two different JavaScript environments and they somehow have different implementation of the Date parsing function.
我們?cè)趇OS中獲得無效日期的原因一定是因?yàn)榇a是在兩個(gè)不同JavaScript環(huán)境中運(yùn)行的,并且它們?cè)谀撤N程度上對(duì)日期解析功能具有不同的實(shí)現(xiàn)。
JavaScript環(huán)境 (JavaScript Environment)
React Native guide has a dedicated section about JavaScript environments.
React Native指南專門介紹了JavaScript環(huán)境 。
When using React Native, you’re going to be running your JavaScript code in two environments:
使用React Native時(shí),您將在兩種環(huán)境中運(yùn)行JavaScript代碼:
In most cases, React Native will use JavaScriptCore, the JavaScript engine that powers Safari. Note that on iOS, JavaScriptCore does not use JIT due to the absence of writable executable memory in iOS apps.
在大多數(shù)情況下,React Native將使用JavaScriptCore (支持SafariJavaScript引擎)。 請(qǐng)注意,在iOS上,由于iOS應(yīng)用程序中沒有可寫的可執(zhí)行內(nèi)存,因此JavaScriptCore不使用JIT。
When using Chrome debugging, all JavaScript code runs within Chrome itself, communicating with native code via WebSockets. Chrome uses V8 as its JavaScript engine.
使用Chrome調(diào)試時(shí),所有JavaScript代碼都在Chrome本身中運(yùn)行,并通過WebSockets與本機(jī)代碼進(jìn)行通信。 Chrome使用V8作為其JavaScript引擎。
While both environments are very similar, you may end up hitting some inconsistencies. We’re likely going to experiment with other JavaScript engines in the future, so it’s best to avoid relying on specifics of any runtime.
盡管兩種環(huán)境非常相似,但您最終可能會(huì)遇到一些不一致之處。 將來我們可能會(huì)嘗試使用其他JavaScript引擎,因此最好避免依賴任何運(yùn)行時(shí)的細(xì)節(jié)。
React Native also uses Babel and some polyfills to have some nice syntax transformers, so some of the code that we write may not be necessarily supported natively by JavascriptCore.
React Native還使用Babel和某些polyfill來具有一些不錯(cuò)的語法轉(zhuǎn)換器,因此JavascriptCore不一定必須支持我們編寫的某些代碼。
Now it is clear that while we debug our app via Chrome debugger, it works because V8 engine handles that. Now try turning off Remote JS Debugging: we can see that the above Date constructor fails, which means it is using JavascriptCore.
現(xiàn)在很明顯,當(dāng)我們通過Chrome調(diào)試器調(diào)試應(yīng)用程序時(shí),它可以工作,因?yàn)閂8引擎可以處理它。 現(xiàn)在嘗試關(guān)閉遠(yuǎn)程JS調(diào)試:我們可以看到上面的Date構(gòu)造函數(shù)失敗,這意味著它正在使用JavascriptCore 。
To confirm this issue, let’s run our app in Xcode and go to the Safari app on MacOS to enter Development menu. Select the active Simulator and choose JSContext on the current iOS app. Remember to turn off Remote JS Debugging so that the app uses JavascriptCore:
為確認(rèn)此問題,讓我們?cè)赬code中運(yùn)行我們的應(yīng)用程序,然后轉(zhuǎn)到MacOS上的Safari應(yīng)用程序以進(jìn)入“開發(fā)”菜單。 選擇活動(dòng)的Simulator,然后在當(dāng)前iOS應(yīng)用上選擇JSContext。 請(qǐng)記住關(guān)閉遠(yuǎn)程JS調(diào)試,以便該應(yīng)用程序使用JavascriptCore:
Now open the Console in Safari dev tools, and we should have access to JavascriptCore inside our app. Try running the above Date constructor to confirm that it fails:
現(xiàn)在,在Safari開發(fā)工具中打開控制臺(tái),我們應(yīng)該可以在應(yīng)用程序內(nèi)訪問JavascriptCore。 嘗試運(yùn)行上面的Date構(gòu)造函數(shù)以確認(rèn)它失敗:
有效日期字符串格式是什么? (What are legit date string formats?)
Since 2016, JavascriptCore supports most ES6 features:
自2016年以來, JavascriptCore支持大多數(shù)ES6功能:
As of r202125, JavaScriptCore supports all of the new features in the ECMAScript 6 (ES6) language specification
從r202125開始 ,JavaScriptCore支持ECMAScript 6(ES6)語言規(guī)范中的所有新功能。
And it was fully confirmed a year later in JSC ? ES6
一年后,它在JSC中得到了充分證實(shí)? ES6
ES2015 (also known as ES6), the version of the JavaScript specification ratified in 2015, is a huge improvement to the language’s expressive power thanks to features like classes, for-of, destructuring, spread, tail calls, and much more
ES2015 (也稱為ES6),在2015年批準(zhǔn)了JavaScript規(guī)范的版本,是一個(gè)巨大的進(jìn)步了語言的表達(dá)能力歸功于像功能類 , 換的 , 解構(gòu) , 傳播 , 尾調(diào)用和更
WebKit’s JavaScript implementation, called JSC (JavaScriptCore), implements all of ES6
WebKitJavaScript實(shí)現(xiàn)(稱為JSC(JavaScriptCore)) 實(shí)現(xiàn)了所有ES6
For more details about JavaScript features supported by different JavaScript engines, visit this ECMAScript comparison table.
有關(guān)不同JavaScript引擎支持JavaScript功能的更多詳細(xì)信息,請(qǐng)?jiān)L問此ECMAScript比較表 。
Now for the date string format, from Date.parse, let’s visit ECMAScript 2015 specification to see what it says about date string format:
現(xiàn)在,從Date.parse中獲取日期字符串格式,讓我們?cè)L問ECMAScript 2015規(guī)范,以了解日期字符串格式的含義:
ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 Extended Format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ
ECMAScript基于ISO 8601擴(kuò)展格式的簡化,為日期時(shí)間定義了字符串交換格式。 格式如下: YYYY-MM-DDTHH:mm:ss.sss Z
Where the fields are as follows:
字段如下:
"T" appears literally in the string, to indicate the beginning of the time element.
"T"字面上出現(xiàn)在字符串中,以指示時(shí)間元素的開始。
So JavascriptCore requires T specifier and V8 can work without it. The fix for now is to always include that T specifier. This way we always follow ECMAScript standards to make sure it works across different JavaScript environments.
因此, JavascriptCore需要T說明符,而V8可以不使用它。 現(xiàn)在的解決方法是始終包含該T指定符。 這樣,我們始終遵循ECMAScript標(biāo)準(zhǔn),以確保其可在不同JavaScript環(huán)境中正常工作。
const date = new Date("2019-01-18 12:00:00".replace(' ', 'T'))And now it returns correct Date object. There may be difference between JavascriptCore on iOS and macOS, and among different iOS versions. The lesson learned here is that we should always test our app thoroughly in production and on devices to make sure it works as expected.
現(xiàn)在,它返回正確的Date對(duì)象。 iOS和macOS上的JavascriptCore之間以及不同的iOS版本之間可能存在差異。 從這里吸取的教訓(xùn)是,我們應(yīng)該始終在生產(chǎn)環(huán)境和設(shè)備上全面測試我們的應(yīng)用程序,以確保其能夠按預(yù)期運(yùn)行。
翻譯自: https://www.freecodecamp.org/news/get-to-know-different-javascript-environments-in-react-native-4951c15d61f5/
總結(jié)
以上是生活随笔為你收集整理的了解React Native中的不同JavaScript环境的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 做梦梦到的东西代表什么
- 下一篇: javascript 作用_JavaSc