## 动态样式
```java
export default class Test extends Component {
render() {
return (
<View>
<Text style={styles.title(18)}>{'好好学习,天天向上'}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
title: (fontSize) => ({
lineHeight: 40,
fontSize: fontSize,
color: 'red',
textAlign: 'center',
}),
})
```
## 链判断运算符(见:ES6语法对象的扩展)
我们在编程开中,如果读取对象内部的某个属性,往往需要判断一下该对象是否存在。比如,要读取`message.body.user.firstName`,安全的写法是写成下面这样:
```java
// 错误的写法
const firstName = message.body.user.firstName;
// 正确的写法
const firstName = (message
&& message.body
&& message.body.user
&& message.body.user.firstName) || 'default';
```
上面例子中,`firstName`属性在对象的第四层,所以需要判断四次,每一层是否有值。
三元运算符`?:`也常用于判断对象是否存在。比如:
```java
const fooInput = myForm.querySelector('input[name=foo]')
const fooValue = fooInput ? fooInput.value : undefined
```
上面例子中,必须先判断`fooInput `是否存在,才能读取`fooInput.value`。
这样的层层判断非常麻烦,因此 [ES2020](https://github.com/tc39/proposal-optional-chaining) 引入了“链判断运算符”(optional chaining operator)`?.`,简化上面的写法。比如:
```java
const firstName = message?.body?.user?.firstName || 'default';
const fooValue = myForm.querySelector('input[name=foo]')?.value
```
上面代码使用了`?.`运算符,直接在链式调用的时候判断,左侧的对象是否为`null `或`undefined`。如果是的,就不再往下运算,而是返回`undefined`。
链判断运算符有三种用法:
- `obj?.prop` // 对象属性
- `obj?.[expr]`. // 同上
- `func?.(...args)` // 函数或对象方法的调用
`?.`运算符相当于一种短路机制,只要不满足条件,就不再往下执行。
## Null 判断运算符(见:ES6语法对象的扩展)
读取对象属性的时候,如果某个属性的值是`null`或`undefined`,有时候需要为它们指定默认值。常见做法是通过`||`运算符指定默认值。比如:
```java
const headerText = response.settings.headerText || 'Hello, world!';
const animationDuration = response.settings.animationDuration || 300;
const showSplashScreen = response.settings.showSplashScreen || true;
```
上面的三行代码都通过`||`运算符指定默认值,但是这样写是错的。开发者的原意是,只要属性的值为`null`或`undefined`,默认值就会生效,但是属性的值如果为空字符串或`false`或`0`,默认值也会生效。
为了避免这种情况,[ES2020](https://github.com/tc39/proposal-optional-chaining) 引入了一个新的 `Null` 判断运算符`??`。它的行为类似`||`,但是只有运算符左侧的值为`null`或`undefined`时,才会返回右侧的值。比如:
```java
const headerText = response.settings.headerText ?? 'Hello, world!';
const animationDuration = response.settings.animationDuration ?? 300;
const showSplashScreen = response.settings.showSplashScreen ?? true;
```
上面代码中,默认值只有在左侧属性值为`null`或`undefined`时,才会生效。
这个运算符的一个目的,就是跟链判断运算符`?.`配合使用,为`null`或`undefined`的值设置默认值。比如:
```java
const animationDuration = response.settings?.animationDuration ?? 300;
```
上面代码中,`response.settings`如果是`null`或`undefined`,就会返回默认值`300`。
## 箭头函数中的 this(见:ES6语法函数的扩展)
在`JavaScript `中`this`对象的指向是可变的,但是在箭头函数中,它是固定化的,也可以称为静态的。
`this`指向的固定化,并不是因为箭头函数内部有绑定`this`的机制,实际原因是箭头函数根本没有自己的`this`,导致内部的`this`就是外层代码块的`this`。正是因为它没有`this`,所以也就不能用作构造函数。
所以,箭头函数转成 ES5 的代码如下:
```java
// ES6
function foo() {
setTimeout(() => {
console.log('id:', this.id);
}, 100);
}
// ES5
function foo() {
var _this = this;
setTimeout(function () {
console.log('id:', _this.id);
}, 100);
}
```
上面代码中,转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的`this`,而是引用外层的`this`。
长期以来,`JavaScript`语言的`this`对象一直是一个令人头痛的问题,在对象方法中使用`this`,必须非常小心。箭头函数”绑定”`this`,很大程度上解决了这个困扰。

React-Native 开发中的小技巧