美文网首页跨平台开发react native
react native:(基本常用JS语法)

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

作者: wg689 | 来源:发表于2017-12-31 14:45 被阅读149次

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

    类型

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

    • null
    • undefined(js 和OC 的区别 就是为定义)
    • boolean (BOOLValue 不同)
    • number
    • string
    • object
    • symbol //在ES6中被加入
      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/let关键字一个变量
      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关键字申明一个常量

      常量定义后,他指向的值不能被改变,但是值本身是可以改变

      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' } // 此处说明本省可以改变
    
    • 使用function关键字申明一个函数
      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语言的缺失
    
    • 使用require/import申明导入其他Js文件中export的变量

      使用require引入一个对象

      // 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命令会发生”变量提升“现象,即变量可以在声明之前使用,值为undefined

      // var 的情况
      console.log(foo); // undefined
      var foo = 'foo';
    
      // let 的情况
      console.log(bar); // ReferenceError
      let bar = 'bar';
    
    • 全局对象

      • 浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
      • 浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
      • Node 里面,顶层对象是global,但其他环境都不支持。
      // 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)
    

    操作符

    • 赋值:比如a = 2中的=
    • 数学:+(加法),-(减法),*(乘法),和/(除法),比如a * 3
    • 复合赋值:+=,-=,*=,和/=都是复合操作符,它们组合了数学操作和赋值
    • 递增/递减:++(递增),--(递减)
    • 对象属性访问:比如console.log()的.
    • 等价性:==(宽松等价),===(严格等价),!=(宽松不等价),!==(严格不等价)
      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
    
    • 逻辑:&&(与),||(或),比如a || b它选择a或b中的一个

    类型间转换

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

    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
    
    • 当我们使用for in遍历数组的时候,拿到的是下标;
    • 当我们使用for of遍历数组的时候,拿到的是元素;
    • 当我们使用map遍历数组的时候,需要传入一个回调function,可以拿到元素和下标、原数组;
    • 当我们使用map遍历数组的时候,需要传入一个回调function,可以拿到元素和下标、原数组;
    • 数组的map方法和forEach方法的主要不同点在返回值,map方法会返回一个数组,forEach方法没有返回值,后续我们在RN界面开发时,会经常使用map方法进行布局,参考以下代码:
      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对象

    • Object的定义

      用 {} 来定义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字符串和对象相互转换

      使用JSON.parse()和JSON.stringify()

      // 字符串转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
    
    • Object相关API

      这里列出一些RN开发中可能会用的,详细API可参见文档MDNJs文档

      1. Object.assign()
        通过复制一个或多个对象来创建一个新的对象。
      2. Object.create()
        使用指定的原型对象和属性创建一个新对象。
      3. Object.defineProperty()
        给对象添加一个属性并指定该属性的配置。
      4. Object.entries()
        返回给定对象自身可枚举属性的[key, value]数组。
      5. Object.values()
        返回给定对象自身可枚举值的数组。
      6. Object.keys()
        返回一个包含所有给定对象自身可枚举属性名称的数组。
      7. Object.is()
        比较两个值是否相同。所有 NaN 值都相等(这与==和===不同)。
      8. Object.setPrototypeOf()
        设置对象的原型(即内部[[Prototype]]属性)。

    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' ]
    
    
    • Json字符串和数组相互转换
      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"}]
    
    • Array相关API

      这里列出一些RN开发中可能会用的,更多API详情可参见文档MDNJs文档

      1. Array.prototype.includes()
        判断当前数组是否包含某指定的值,如果是返回 true,否则返回 false。
      2. Array.prototype.slice()
        抽取当前数组中的一段元素组合成一个新数组。
      3. Array.prototype.find()
        找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 undefined。
      4. Array.prototype.findIndex()
        找到第一个满足测试函数的元素并返回那个元素的索引,如果找不到,则返回 -1。
      5. Array.prototype.entries()
        返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。
      6. Array.prototype.values()
        返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。
      7. Array.prototype.keys()
        返回一个数组迭代器对象,该迭代器会包含所有数组元素的键。
      8. Array.prototype.map()
        返回一个由回调函数的返回值组成的新数组。
      9. Array.prototype.forEach()
        为数组中的每个元素执行一次回调函数
      10. Array.prototype.some()
        如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
      11. Array.prototype.indexOf()
        返回数组中第一个与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。
      12. Array.prototype.lastIndexOf()
        返回数组中最后一个(从右边数第一个)与指定值相等的元素的索引,如果找不到这样的元素,则返回 -1。

    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' ]
    
    • Set 相关API
      这里列出一些RN开发中可能会用的,更多API详情可参见文档MDNJs文档
    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'
      // }
    
    • Map相关API
      这里列出一些RN开发中可能会用的,更多API详情可参见文档MDNJs文档
    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);
    

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/ftmugxtx.html