跨平台开发react native

react native:(基本常用JS语法)

2017-12-31  本文已影响149人  wg689

1.类型&变量申明&作用域

类型

js中一共有7种内建类型:

  console.log(typeof null)       //  Object(ECMAScript规范的一个特殊约定)
  console.log(typeof undefined)  //  undefined
  console.log(typeof true)       //  boolean
  console.log(typeof 1.34)       //  number
  console.log(typeof 'foo')      //  string
  console.log(typeof {jack: 'name'})  //  Object
  console.log(typeof Symbol())   //  symbol

变量申明

在静态语言(如c、java、oc)中,我们通常使用变量类型或类、结构体等来申明变量、常量。
而在Js这种动态语言中变量没有类型,值才有类型。
变量可以在任何时候持有任何类型的值。

  var a = 42
  console.log(typeof a) // "number"
  console.log(a) // "42"

  a = true
  console.log(typeof a) // "boolean"
  console.log(a) // "true"

  let b = {foo: 'foo', bar: 'bar'}
  console.log(typeof b) // "number"
  console.log(b) // "42"

  b = Symbol.for('a symbol object')
  console.log(typeof b) // "symbol"
  console.log(b) // "true"

  const foo = 1
  foo = 2 //TypeError: Assignment to constant variable

  const bar = {a: 'a', b: 'b'}
  bar.c = 'c'
  console.log(bar); //{ a: 'a', b: 'b', c: 'c' } // 此处说明本省可以改变
  fuction bar () {
    return 1
  }
  console.log(bar());  // 1

  function boo (a, b=0) {
    console.log(a, b)
  }
  boo(1)  // 1  0
  boo(1, 2)  // 1  2
//和c语言类似,和OC不同, 可以有默认参数值,这是OC语言的缺失
  // a.js文件
  module.exports = {
    foo : function(a) {
      console.log('foo function calling', a);
    },
    bar : 'hello'
  };

  // b.js文件
  var a = require('./a.js')
  console.log(a);
  a.foo(123)
  // { foo: [Function: foo], bar: 'hello' }
  // foo function calling 123

使用import引入一个对象, imort语法是ES6[ECMA2005]中引入的
原生nodejs环境不支持import语法,我们可以使用babel转码器进行代码转换
使用npm初始化一个工程,并集成babel插件

  $ npm init
  $ npm install --save-dev babel-cli
  $ npm install --save-dev babel-preset-es2015

在工程根目录下新建.rcbabel文件,该文件是babel转码的配置文件,文件中添加配置

  {
    "presets": [ "es2015" ],
    "plugins": []
  }

修改package.json文件的scripts内容

  {
    "name": "test",
    "version": "1.0.0",
    "description": "test nodejs",
    "main": "index.js",
    "scripts": {
      "dev": "babel-node index.js",
      "test": "echo \"Error: no test specified\" && exit 1"
    },
    "author": "",
    "license": "MIT",
    "dependencies": {
      "react": "^16.2.0"
    },
    "devDependencies": {
      "babel-preset-es2015": "^6.24.1"
    }
  }

a.js文件

  const foo = function(a) {
    console.log('foo function calling', a)
  }
  const bar = 'hello'

  export {foo, bar}

index.js文件

  import {foo, bar} from './a' //文件相对路径

  foo(1)
  console.log(bar)
  // foo function calling 1
  // hello

作用域

  {
    let a = 'foo'
    var b = 'bar'
    const c = 'ban'
    console.log(a, b, c) // foo bar ban
  }
  console.log(a) // ReferenceError: a is not defined
  console.log(b) // bar
  console.log(c) // ReferenceError: c is not defined

在以上代码中,我们在代码块中分别用let、var、const申明了a、b、c
在代码块外调用时,let和const申明的变量失效,var申明的变量仍然有值

let和const具有块级作用域,申明的变量只在作用域内部有效

  // var 的情况
  console.log(foo); // undefined
  var foo = 'foo';

  // let 的情况
  console.log(bar); // ReferenceError
  let bar = 'bar';
  // a.js
  function bar () {
    console.log('function bar is called');
    global.g = 1
  }
  export {bar}

  // index.js
  import {bar} from './a'
  bar()
  console.log(global.g);
  // function bar is called
  // 1

2.基本语法

语句

js的语句可以以';'分号结尾,也可以不带';'分号

  let a = 2
  let b = 2 * a;
  console.log(a, b); // 2 4
  let c = '2'
  console.log(c)

操作符

  let a = 2
  let b = '2'
  console.log(a==b);  //true
  console.log(a===2); //true
  console.log(a===b); //false
  let a = 3
  let b = '2'
  console.log(a > b);  //true

类型间转换

使用内建类型函数去强制转换

let b = Number('3')
console.log(b); // 3

b = Number('a')
console.log(b); // NaN

b = Number('1 0')
console.log(b); // NaN

b = Number('153.23')
let c = String(b)
console.log(b); // 153.23
console.log(c); // 153.23

条件控制语句

支持:if else ,三目运算符,switch case

  let xx = 1
  if (xx == '1' || typeof xx == 'number') {
    console.log('equal');
  } else {
    console.log('not equal');
  }
  // equal
  console.log(xx === 1 ? 1 : 0); // 1

循环&遍历

支持for/break/continue 、while、do/while、for in / for of/ Map / forEach

for in / for of / Map / forEach比较

  // example for in
  let array = ['a', 'b', 'c', 'd']
  for (let a in array) {
    console.log(a);
  }
  // 0
  // 1
  // 2
  // 3
  for (let a of array) {
    console.log(a);
  }
  // a
  // b
  // c
  // d
  array.map( function (item, index, orgin) {
    console.log(item, index);
  })
  // a 0
  // b 1
  // c 2
  // d 3
  array.forEach(  function (item, index, orgin) {
    console.log(item, index);
  })
  // a 0
  // b 1
  // c 2
  // d 3
  let array = ['a', 'b', 'c', 'd']
  console.log(array.map( function (item, index, orgin) {
    console.log(item, index);
    return 1
  }));
  // a 0 [ 'a', 'b', 'c', 'd' ]
  // b 1 [ 'a', 'b', 'c', 'd' ]
  // c 2 [ 'a', 'b', 'c', 'd' ]
  // d 3 [ 'a', 'b', 'c', 'd' ]
  // [ 1, 1, 1, 1 ] map 返回的数组
  console.log(array.forEach(  function (item, index, orgin) {
    console.log(item, index);
    return 1
  }));
  // a 0
  // b 1
  // c 2
  // d 3
  // undefined forEach 无返回值

3.原型与Object、Array、Set、Map数据结构

原型

prototype是函数对象的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。

  console.log(Object.prototype); // {}
  console.log(Number.prototype); // [Number: 0]
  console.log(Boolean.prototype); // [Boolean: false]
  console.log(Symbol.prototype);  // Symbol {}
  function Sum(a, b) {
    return a+b
  }
  let sum = new Sum()
  Sum.prototype.multiply = function(a, b) {
    return a * b
  }
  console.log(sum.constructor(2, 3)); // 5
  console.log(sum.multiply(2, 3)); // 6
  console.log(Sum.prototype); // sum {}
  console.log(sum.__proto__); // sum {}

_proto_是一个普通对象(上面提到的函数对象也属于普通对象)拥有的内置属性,是JS内部使用寻找原型链的属性。

  let foo = {
    a: 'a',
    sum(a, b) {
      return a+b
    }
  }
  let bar = {
    b: 'b'
  }
  console.log(foo.__proto__); // {}
  Object.setPrototypeOf(bar, foo);
  console.log(bar); // { b: 'b' }
  console.log(bar.a); // a
  console.log(bar.sum(1, 2)); // 3

对象的_proto_属性指向是对象的原型类型,在上面的例子中foo._proto_的值是{},foo是一个Object对象,在以下代码中,我们查看一个数组的_proto_属性,值为 [ ], array是一个数组

  let array = [1, 2, 3, 4]
  console.log(array.__proto__); // []
  const set = new Set([1, 2, 3, 4]);
  console.log(set.__proto__); // set {}
  console.log(set.__proto__.__proto__); // {}
  console.log(set.__proto__.__proto__.__proto__); // null
  const map = new Map([['a', 'a'],['b', 'b'],['c', 'c']]);
  console.log(map.__proto__); // map {}
  console.log(map.__proto__.__proto__); // {}
  console.log(map.__proto__.__proto__.__proto__); // null

js的继承就是通过原型链来实现的: 实际上js没有继承,但是_proto_却起到了类似继承的作用。js中所有的对象起源都是一个空对象,我们把这个空对象叫做原始对象。所有的对象通过_proto_回溯最终都会指向(所谓的指向类似C中的指针,这个原始对象是唯一的,整个内存中只会存在一个原始对象)这个原始对象。

  let people = {
    name: 'foo',
    getName() {
      return this.name
    }
  }
  let student = {
    grader: `1`,
  }
  Object.setPrototypeOf(student, people);
  let aa = Object.create(student)

  aa.sex = 1
  console.log(aa.name, aa.grader); // foo 1
  console.log(aa.getName()); // foo

Object对象

  let c = `c`
  let foo = {
    a: 'string',
    b: true,
    c,
    d: 1.52,
    f: function(a, b) {
      return a+b
    },
    g(a, b) {
      return a-b
    }
  }
  console.log(foo); // { a: 'string', b: true, c: 'c', d: 1.52, f: [Function: f], g: [Function: g] }
  console.log(foo.f(3, 2)); // 3
  console.log(foo.g(4, 2)); // 2
  // 字符串转json
  let jsonStr = `{ "name": "douyu", "department": "research and development" }`;
  let obj = JSON.parse(jsonStr);
  console.log(obj); // { name: 'douyu', department: 'research and development' }

  // json转字符串
  let str = JSON.stringify(obj);
  console.log(str);  // {"name":"douyu","department":"research and development"}

  let foo = {
    a: 'string',
    g(a, b) {
      return a-b
    }
  }
  console.log(foo.a); // string
  console.log(foo['a']); // String
  console.log(foo['g']); // [Function: g]
  console.log(foo['g'](5, 2)); // 3

Array

  let array1 = [1, 2, 3, 4, 'a', [1, 2]]
  array1['outer'] = 'outer'
  array1['foo'] = 'foo'
  console.log(array1);
  // [ 1, 2, 3, 4, 'a', [ 1, 2 ], outer: 'outer', foo: 'foo' ]

  for (let entry of array1.entries()) {
    console.log(entry);
  }
  // [ 0, 1 ]
  // [ 1, 2 ]
  // [ 2, 3 ]
  // [ 3, 4 ]
  // [ 4, 'a' ]
  // [ 5, [ 1, 2 ] ]

  array1[7] = 'sss'
  for (let entry of array1.entries()) {
    console.log(entry);
  }
  // [ 0, 1 ]
  // [ 1, 2 ]
  // [ 2, 3 ]
  // [ 3, 4 ]
  // [ 4, 'a' ]
  // [ 5, [ 1, 2 ] ]
  // [ 6, undefined ]
  // [ 7, 'sss' ]

  let jsonStr = `[
    { "name": "douyu", "department": "research and development" },
    { "name": "douyu", "department": "research and development" }
  ]`
  let obj = JSON.parse(jsonStr)
  console.log(obj.__proto__) // []

  let str = JSON.stringify(obj)
  console.log(str) // [{"name":"douyu","department":"research and development"},{"name":"douyu","department":"research and development"}]

Set

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

let set = new Set()
set.add(1)
set.add(1)
set.add('a')
console.log(set); // Set { 1, 'a' }
for (let entry of set.entries()) {
  console.log(entry);
}
// [ 1, 1 ]
// [ 'a', 'a' ]
  1. Set.prototype.add(value)
    在Set对象尾部添加一个元素。返回该Set对象。
  2. Set.prototype.clear()
    移除Set对象内的所有元素。
  3. Set.prototype.delete(value)
    移除Set的中与这个值相等的元素,返回Set.prototype.has(value)在这个操作前会返回的值(即如果该元素存在,返回true,否则返回false)。Set.prototype.has(value)在此后会返回false。
  4. Set.prototype.has(value)
    返回一个布尔值,表示该值在Set中存在与否。

Map

键值对存储结构, es6以后的规范中,key可以使用任意类型的值,包括对象,数组等

  let obj = { foo: 'foo'}
  let array = [1, 2, 3, 4]
  let map = new Map()
  map.set('string', 'string')
  map.set(obj, 'obj')
  map.set(array, 'array')
  console.log(map.size); //3
  console.log(map);
  // Map {
  //   'string' => 'string',
  //   { foo: 'foo' } => 'obj',
  //   [ 1, 2, 3, 4 ] => 'array'
  // }
  1. Map.prototype.clear()
    移除Map对象的所有键/值对 。
  2. Map.prototype.delete(key)
    移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用Map.prototype.has(key)会返回false。
  3. Map.prototype.get(key)
    返回键对应的值,如果不存在,则返回undefined。
  4. Map.prototype.has(key)
    返回一个布尔值,表示Map实例是否包含键对应的值。
  5. Map.prototype.set(key, value)
    设置Map对象中键的值。返回该Map对象。

解构赋值

解构赋值是指变量赋值的一种常用方式,包含两部操作:

  1. 在从对象、数组中提取值
  2. 将提取的值赋给变量

先看下面一段代码,

function getUserInfo() {
  return {
    id: 1003,
    name: 'foo',
    sex: 1,
    firends: [
      {
        name: 'foo1',
        sex: 1,
      },
      {
        name: 'foo2',
        sex: 2
      }
    ]
  }
}

const {id, name, sex:isMan, firends, isVip = 0} = getUserInfo()

console.log(id);  // 1003
console.log(name); // true
console.log(isMan); // 1
for (let firend of firends) {
  console.log(firend);
}
// { name: 'foo1', sex: 1 }
// { name: 'foo2', sex: 2 }
console.log(isVip); // 1

在RN开发中,使用解构赋值进行组件化的

个人信息Component

// Example1Header.js
import React from 'react'
import { View, Image, Text, StyleSheet } from 'react-native'

class Example1Header extends React.PureComponent {
  render () {
    // const {name, sex, avator, isVip} = this.props.userInfo
    return (
      <View style={styles.container} >
        <Image style={styles.avator} source={{uri: this.props.avator}} />
        <View style={styles.info}>
          <Text style={styles.name}> {this.props.name} </Text>
          <Text style={styles.sex}> {this.props.sex===1 ? '男':'女'} </Text>
        </View>
        {this.props.isVip && <Text style={styles.vip}> VIP用户 </Text>}
      </View>
    )
  }
}

const styles = StyleSheet.create ({
  container: { flexDirection:'row', justifyContent:'flex-start', alignItems:'center', backgroundColor: '#dcdcdc', height: 100, marginTop: 10 },
  avator: {width: 60, height: 60, marginLeft: 15},
  name: {marginLeft: 15, fontSize: 18, fontWeight: 'bold', color: '#000000'},
  info: {marginLeft: 15, flexDirection: 'column', justifyContent: 'space-between', alignItems: 'center'},
  sex: {marginLeft: 15, fontSize: 15, color: '#999'},
  vip: {marginLeft: 15, fontSize: 15, color: '#ff0000'}
})

export default Example1Header

好友信息Component

// Example1Firends.js
import React from 'react'
import { View, Image, Text, StyleSheet } from 'react-native'

class Example1Firends extends React.PureComponent {

  _renderFirends(firends) {
    return (
      firends.map( (item, index) => {
        return (
          <View style={styles.firendItem} key={index}>
            <Text>{item.name}</Text>
            <Text>{item.sex===1 ? '男':'女'}</Text>
          </View>
        )
      })
    )
  }

  render () {
    const number = `共有${this.props.firends.length}位好友:`
    return (
      <View style={styles.container} >
        <Text style={styles.firendsnumber}> {number} </Text>
        {this._renderFirends(this.props.firends)}
      </View>
    )
  }
}

const styles = StyleSheet.create ({
  container: { flexDirection: 'column', justifyContent: 'flex-start',  backgroundColor: '#dcdcdc', marginTop: 10 },
  firendsnumber: { color: '#333', fontSize: 15 },
  firendItem: { flexDirection:'row', justifyContent: 'space-between', alignItems: 'center', padding: 10, height: 30  }
})

export default Example1Firends

测试数据js文件

GetUserInfo = () => {
  return {
    id: 1003,
    isVip: true,
    name: 'zhangsan',
    sex: 1,
    avator: 'https://www.baidu.com/img/bd_logo1.png',
    firends: [
      {
        name: 'lisi',
        sex: 1,
      },
      {
        name: 'wangwu',
        sex: 2
      }
    ]
  }
}
export { GetUserInfo }

整体页面Component

import React from 'react'
import { View } from 'react-native'
import { GetUserInfo } from './data/Example1Data'
import Example1Header from './component/Example1Header'
import Example1Firends from './component/Example1Firends';

class Example1 extends React.PureComponent {

  render () {
    let {sex, name, isVip, avator, firends} = GetUserInfo()
    return (
      <View style={{ flex:1 }}>
        <Example1Header sex={sex} name={name} isVip={isVip} avator={avator} />
        <Example1Firends firends={firends} />
      </View>
    )
  }
}
export default Example1

//index.js文件中注册Example1 component
import { AppRegistry } from 'react-native';
import Example1 from './App/Example1'
AppRegistry.registerComponent('helloreactnative', () => Example1);
上一篇下一篇

猜你喜欢

热点阅读