React Native学习笔记(一)

本文介绍了学习React Native需要了解的JavaScript基本语法及概念。

本文首发:http://yuweiguocn.github.io/

《无题·相见时难别亦难》
相见时难别亦难,东风无力百花残。
春蚕到死丝方尽,蜡炬成灰泪始干。
晓镜但愁云鬓改,夜吟应觉月光寒。
蓬山此去无多路,青鸟殷勤为探看。
—唐,李商隐

JavaScript基本语法及概念

JavaScript是一种脚本语言,ECMA(European Computer Manufacturers Association)组织定制了JavaScript语言的标准,被称为ECMAScript标准。最新版ECMAScript 7标准(简称ES7)已经在2016年6月正式发布了,所以,讲到JavaScript的版本,实际上就是说它实现了ECMAScript标准的哪个版本。

由于JavaScript的语法和Java语言类似,这里我们只介绍有区别或需要了解的语法及概念。

变量

声明一个变量用 var 语句,比如:

var a; // 声明了变量a,此时a的值为undefined
var $b = 1; // 声明了变量$b,同时给$b赋值,此时$b的值为1
var s_007 = '�007'; // s_007是一个字符串
var Answer = true; // Answer是一个布尔值true
var t = null; // t的值是null

常量

ES6标准引入了新的关键字 const 来定义常量, constlet 都具有块级作用域:

const PI = 3.14;

对象

JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。JavaScript的对象用于描述现实世界中的某个对象。例如,为了描述小明这个淘气的小朋友,我们可以用若干键值对来描述他:

var xiaoming = {
    name: '小明',
    birth: 1990,
    school: 'No.1 Middle School',
    height: 1.70,
    weight: 65,
    score: null
}

JavaScript用一个 {...} 表示一个对象,键值对以 xxx: xxx 形式声明,用,隔开。获取属性值:

xiaoming.name; // '小明'
xiaoming.birth; // 1990

函数

在JavaScript中,定义函数的方式如下:

function abs(x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

如果没有 return 语句,函数执行完毕后也会返回结果,只是结果为 undefined 。由于JavaScript的函数也是一个对象,上述定义的 abs() 函数实际上是一个函数对象,而函数名 abs 可以视为指向该函数的变量。

因此,第二种定义函数的方式如下:

var abs = function (x) {
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
};

在这种方式下, function (x) { ... } 是一个匿名函数,它没有函数名。但是,这个匿名函数赋值给了变量 abs ,所以通过变量 abs 就可以调用该函数。
上述两种定义完全等价,注意第二种方式按照完整语法需要在函数体末尾加一个;,表示赋值语句结束。

调用定义的函数:

abs(10); // 返回10
abs(-9); // 返回9

箭头函数

ES6标准新增了一种新的函数:Arraw Function(箭头函数)。为什么叫Arrow Function?因为它的定义用的就是一个箭头:

x => x * x

上面的箭头函数相当于:

function (x) {
    return x * x;
}

箭头函数相当于匿名函数,并且简化了函数定义。箭头函数有两种格式,一种像上面的,只包含一个表达式,连 { ... } 和 return 都省略掉了。还有一种可以包含多条语句,这时候就不能省略 { ... } 和 return :

x => {
    if (x > 0) {
        return x * x;
    } else {
        return - x * x;
    }
}

上面的例子是只有一个参数的箭头函数,无参的箭头函数或多个参数的箭头函数需要使用圆括号:

var a = () => 4 * 4;

var xy = (x,y) => x * y;

strict模式

strict模式是用于避免由于JavaScript设计缺陷而导致潜在的严重的bug,启用strict模式的方法是在JavaScript代码的第一行写上:

'use strict';

这是一个字符串,不支持strict模式的浏览器会把它当做一个字符串语句执行,支持strict模式的浏览器将开启strict模式运行JavaScript。

变量作用域

在JavaScript中,用 var 声明的变量实际上是有作用域的。如果一个变量在函数体内部声明,则该变量的作用域为整个函数体,在函数体外不可引用该变量:

'use strict';
function foo() {
    var x = 1;
    x = x + 1;
}
x = x + 2; // ReferenceError! 无法在函数体外引用变量x

块级作用域 let

由于JavaScript的变量作用域实际上是函数内部,我们在 for 循环等语句块中是无法定义具有局部作用域的变量的:

'use strict';
function foo() {
    for (var i=0; i<100; i++) {
        //
    }
    i += 100; // 仍然可以引用变量i
}

为了解决块级作用域,ES6引入了新的关键字 let ,用 let 替代 var 可以声明一个块级作用域的变量:

'use strict';
function foo() {
    var sum = 0;
    for (let i=0; i<100; i++) {
        sum += i;
    }
    i += 1; // SyntaxError
}

比较运算符

JavaScript在设计时,有两种比较运算符:
第一种是 == 比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是 === 比较,它不会自动转换数据类型,如果数据类型不一致,返回 false ,如果一致,再比较。
由于JavaScript这个设计缺陷,不要使用 == 进行比较,始终坚持使用 === 进行比较

模块

ES6引入了模块的概念,一个模块就是一个独立的js文件。ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。模块功能主要由两个命令构成:export 和 importexport 命令用于规定模块的对外接口,import 命令用于输入其他模块提供的功能。

profile.js

export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

// or
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

下面的 import 命令,用于加载 profile.js 文件,并从中输入变量。大括号里面的变量名,必须与被导入模块( profile.js )对外接口的名称相同。import 后面的 from 指定模块文件的位置,可以是相对路径,也可以是绝对路径,.js后缀可以省略。如果 import 指定的是文件夹的路径,默认会去找指定目录下的index.js文件。如果只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。
main.js

// main.js
import {firstName, lastName, year} from './profile.js';

function setName(element) {
  element.textContent = firstName + ' ' + lastName;
}

除此之外,我们还可以使用** export default **命令为模块指定默认输出:

export-default.js

export default function () {
  console.log('foo');
}

其他模块加载该模块时,import 命令可以为该匿名函数指定任意名字:

import customName from './export-default';
customName(); // 'foo'

上面代码的 import 命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面不使用大括号。export default 命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此 export deault 命令只能使用一次。所以, import 命令后面才不用加大括号,因为只可能对应一个方法。

如果想在一条 import 语句中,同时输入默认方法和其他变量,可以写成下面这样:

import customName, { otherMethod } from './export-default';

class

ES6 引入了 Class(类)这个概念,通过使用 class 关键字,可以定义一个类:

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}

上面代码定义了一个类,可以看到里面有一个 constructor 方法,这就是构造方法,而 this 关键字则代表实例对象。Point 类除了构造方法,还定义了一个 toString 方法。

注意,定义类的方法的时候,前面不需要加上 function 这个关键字,直接把函数定义放进去了就可以了。

使用 new 关键字创建一个类的实例。

var point = new Point(2, 3);
point.toString();

创建匿名类:

let person = new class {
    constructor(name) {
        this.name = name;
    }
    sayName() {
        console.log(this.name);
    }
}('张三');

person.sayName(); // "张三"

使用 extends 关键字继承一个类:

class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y); // 调用父类的constructor(x, y)
        this.color = color;
    }
    toString() {
        return this.color + ' ' + super.toString(); // 调用父类的toString()
    }
}

在Class内部可以使用 get 和 set 关键字自定义属性的getter和setter方法:

class MyClass {
    constructor() {
    // ...
    }
    get prop() {
        return 'getter';
    }
    set prop(value) {
        console.log('setter: '+value);
    }
}
let inst = new MyClass();
inst.prop = 123; // setter: 123
console.log(inst.prop); // 'getter'

使用 static 关键字定义静态方法,静态方法可以直接使用类名调用:

class Foo {
    static classMethod() {
        return 'hello';
    }
}
Foo.classMethod() // 'hello'

查看React Native学习笔记相关文章

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容