# 通過JS使用原生API
## 概覽
NativeScript允許你從底層平臺使用所有原生API。要完成這個行為,后臺將發生很多事情。其中之一是 marshalling ?編組?編譯?——JS與IOS的 Objective-C 數據類型和 Android 的Java數據類型之間的轉換。
本文中,你將學習如何通過JS使用不同的數據類型參數來調用原生API。更多信息,參看 [iOS Runtime](http://docs.nativescript.org/runtimes/ios/marshalling/Marshalling-Overview.html) 和 [Android Runtime](http://docs.nativescript.org/runtimes/android/marshalling/overview.html) 章節的有關數據轉換的具體平臺資源。
## **[數字型](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#numeric-types)**
當地原生的數值類型(例如,IOS的char,int,float,double 和 Android的 byte, short, int, long, double, float )都將被隱式地轉換為JavaScript的數值,反之亦然。例如,當你在IOS上運行下面的代碼:
> `// iOS`
>
> `console.log('pow(2.5, 3) = ', pow(2.5, 3));`
iOS Runtime將轉換JS數字字面量為原生的 double類型,并把它們傳遞給原生函數 `pow(double x, double y)` 。返回的原生整形將自動地轉換為JS數字并傳遞給 `console.log()` 。這在 Android 上同樣有效:
> `// Android`
>
> `console.log('min(3, 4) = ', java.lang.Math.min(3, 4));`
原生的 `java.lang.Math.min()` 要求有兩個整形。 Android Runtime 知道 `java.lang.Math.min()` 的簽名并將字面量3和4用JAVA整形數據類型翻譯成它們的表述。返回的整形同樣也自動地翻譯成JS數字并傳遞給 `console.log()` 。
## **[類和對象](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#classes-and-objects)**
所有原生的類在JS世界里由一個構造函數代表。一個原生類里的每一個靜態方法在JS構造函數之上成為一個函數,且每個實例方法在JS原型之上成為一個函數。在IOS上執行這段代碼:
> `// iOS`
>
> `var array = new NSMutableArray();`
>
> `array.addObject(new NSObject());`
iOS Runtime調用 `[[NSMutableArray alloc] init]` 且返回的原生對象被轉換為JS對象包裝器并指派為 `array1` 。該包裝器擁有 `NSMutableArray` (及其前身)的原型鏈上的所有實例方法,所以它們可以從JS調用。為了從JS里使用更方便,方法名輕微地有所改變(比如 `tObject:atIndexedSubscript:` 在JS里命名為 `setObjectAtIndexedSubscript()`)。 Android 里同樣有效:
> `// Android var context = ...;`
>
> `var button = new android.widget.Button(context);`
>
> `button.setText("My Button");// "My Button" is converted to java.lang.String`
## **[字符串](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#string)**
JavaScript 字符串在Android上隱式地整理成 `java.lang.String` , 在IOS上是`NSString` ,反之亦然。
> `// iOS`
>
> `var button = new UIButton();`
>
> `button.setTitleForState('Button title', UIControlStateNormal); // 'Button title' 轉換成 NSString`
>
> `console.log(button.titleLabel.text); // 返回的 NSString 轉換成 JavaScript string`
>
> ---
>
> `// Android`
>
> `var file = new java.io.File('myfile.txt'); // 'myfile.txt' 轉換成 java.lang.String`
這里有個例外是 `NSString` 類之上聲明作為返回的 `instancetype` 的方法——初始化方法和工廠方法。這意味著對 `NSString.stringWithString` 的調用,其在 Objective-C里的返回類型是 `instancetype` ,將返回一個包裝器,外面包裹著一個 `NSString` 實例,相對JS字符串而言。
> ### 例外:
>
> 在`NSString` 類之上聲明作為返回的 `instancetype` 的方法 \(如,初始化方法和工廠方法\) 。例如,對 `NSString.stringWithString` 的調用在 Objective-C 里結果是返回 `instancetype` 。在你的 NativeScript 代碼里,類似的調用會返回包裹著一個 `NSString` 實例的包裝器而替代JS字符串。
## [**布爾型**](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#boolean)
JavaScript boolean values are implicitly marshalled to `boolean` on Android and `BOOL` on iOS and vice versa.
JS的 boolean 值隱式地整理成 Android 的 `boolean` 和IOS的 `BOOL` ,反之亦然。
> `// iOS `
>
> `var str = NSString.stringWithString('YES'); `
>
> `var isTrue = str.boolValue(); `
>
> ---
>
> `// Android `
>
> `var str = new java.lang.String('Hello world!'); `
>
> `var result = str.endsWith('world!'); `
>
> `console.log(result); // true `
# [**數組**](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#array)
JS數組映射為專門的 Android 上的Java數組和IOS上的 `NSArray` 。
> `// iOS `
>
> `// nsArray is not a JavaScript array but a JavaScript wrapper around a native NSArray `
>
> `var nsArray = NSArray.arrayWithArray(['Four', 'Five', 'Two', 'Seven']); `
>
> `var jsArray = ['One', 'Two', 'Three'];`
>
> ` // pure JavaScript array `
>
> `var firstCommon = nsArray.firstObjectCommonWithArray(jsArray); `
>
> `console.log(firstCommon); // Two `
The following code snippet shows how to call a `ns.example.Math.minElement(int[] array)` from JavaScript:
下面的代碼片段顯示了如何從 JS 調用一個 `ns.example.Math.minElement(int[] array)` :
> `// Android `
>
> `var numbers = [3, 6, 19, -2, 7, 6]; `
>
> `var min = ns.example.Math.minElement(numbers); // -2 `
# [**Undefined & Null**](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#undefined--null)
JavaScript [Undefined](http://www.w3schools.com/jsref/jsref_undefined.asp) & [Null](http://www.w3schools.com/js/js_datatypes.asp) 映射為 Java null 指針 ,而 Objective-C nil.的原生 null 值映射為 JavaScript null.
> `// iOS `
>
> `console.log(NSStringFromClass(null)); // null`
>
> ---
>
> `// Android `
>
> `var context = ...; `
>
> `var button = new android.widget.Button(context); `
>
> `button.setOnClickListener(undefined); // the Java call will be made using the null keyword `
# [**也可參考**](http://docs.nativescript.org/core-concepts/accessing-native-apis-with-javascript#see-also)
* [Marshalling in Android Runtime](http://docs.nativescript.org/runtimes/android/marshalling/overview.html)
* [Marshalling in iOS Runtime](http://docs.nativescript.org/runtimes/ios/marshalling/Marshalling-Overview.html)