React-Native_02:语法篇

1.简介

ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

JavaScript的创造者Netscape公司,之后将JavaScript提交给国际标准化组织ECMA,希望这种语言能够成为国际标准,ECMAScript和JavaScript的关系是,前者是后者的规格,后者是前者的一种实现,

之所以不叫JavaScript,有两个原因。

一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。

二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。

在线将ES6代码转为ES5代码(https://babeljs.io/repl/)

Babel是一个广泛使用的ES6转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。这意味着,你可以用ES6的方式编写程序,又不用担心现有环境是否支持。

2.变量声明

ES5只有2种声明变量的方法:var、function。

ES6共有6种声明变量的方法:var、function、let、const、import(require)、class。

2.1 var命令

var a = 10;

var b = 20;

var c = 30;

var a = 10,b = 20,c = 30;

var arr = [1,2,3,4,5];

var a = arr[0];

var b = arr[1];

var c = arr[3];

var obj = {

name: ‘gary‘,

age: 20

}

var a = obj.name;

var b = obj.age;

没有用var关键字,使用直接赋值方式声明的是全局变量,例如:

a = 10;

全局对象是最顶层的对象,在浏览器环境指的是window对象,在Node.js指的是global对象。ES5之中,全局对象的属性与全局变量是等价的。

window.a = 1;

a // 1

a = 2;

window.a // 2

2.2 function命令

var 方式定义的函数,不能先调用函数,后声明,只能先声明函数,然后调用。

function方式定义函数可以先调用,后声明。

aaa();//这样调用就会出错

var aaa = function(){

alert("aaa");

}

aaa();//这样就不会出错

//先调用后声明

bbb();

function bbb(){

alert("bbb");

}

2.3 let命令

块级有效

ES5只有全局作用域和函数作用域,没有块级作用域,在ES6中,let实际上为JavaScript新增了块级作用域。

用来声明变量,用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

function f1() {

let n = 5;

if (true) {

let n = 10;

}

console.log(n); // 5

}

for循环的计数器,就很合适使用let命令。例如:

var a = [];

for (var i = 0; i < 10; i++) {

a[i] = function () {

console.log(i);

};

}

a[5](); //10

a[6](); // 10

var a = [];

for (let i = 0; i < 10; i++) {

a[i] = function () {

console.log(i);

};

}

a[5](); //5

a[6](); // 6

变量提升

let不像var那样会发生“变量提升”现象??????

console.log(foo); // 输出undefined

console.log(bar); // 报错ReferenceError

var foo = 2;

let bar = 2;

实测结果两个都是undefined,应该是网上资料错误,可以通过Babel来了解底层原理

暂时性死区

只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。

var tmp=‘dev‘;

if (true) {

console.log(tmp);

let tmp;

console.log(tmp);

tmp = 123;

console.log(tmp);

}

在let命令声明变量tmp之前,都属于变量tmp的“死区”。

不允许重复声明

let不允许在相同作用域内,重复声明同一个变量。

// 报错

function test() {

let a = 10;

var a = 1;

}

// 报错

function test() {

let a = 10;

let a = 1;

}

因此,不能在函数内部重新声明参数。

function func(arg) {

let arg; // 报错

}

function func(arg) {

{

let arg; // 不报错

}

}

2.4 const命令

const声明一个只读的常量。一旦声明,就必须立即初始化,不能留到以后赋值。也不能改变。

const PI = 3.1415;

console.log(PI); // 3.1415

PI = 3;// TypeError: Assignment to constant variable.

const的作用域与let命令相同:只在声明所在的块级作用域内有效,声明的常量,也与let一样不可重复声明。

const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。

const foo = {};

foo.prop = 123;

console.log(foo.prop);// 123

foo = {}; // TypeError: "foo" is read-only

var命令和function命令声明的全局变量,依旧是全局对象的属性;

let命令、const命令、class命令声明的全局变量,不属于全局对象的属性。也就是说,从ES6开始,全局变量将逐步与全局对象的属性脱钩。

var a = 1;

// 如果在Node的REPL环境,可以写成global.a

// 或者采用通用方法,写成this.a

window.a // 1

let b = 1;

window.b // undefined

2.5 import命令

模块的功能主要由 export 和 import 组成.每一个模块都有自己单独的作用域,模块之间的相互调用关系是通过 export 来规定模块对外暴露的接口,通过import来引用其它模块提供的接口。同时还为模块创造了命名空间,防止函数的命名冲突。

ES6将一个文件视为一个模块,通过export 向外输出了一个变量。一个模块也可以同时往外面输出多个变量。

//test.js

var name = ‘Rainbow‘;

var age = ‘24‘;

export {name, age};

定义好模块的输出以后就可以在另外一个模块通过import引用。

import {name, age} from ‘./test.js‘

整体输入,module指令

//test.js

export function getName() {

return name;

}

export function getAge(){

return age;

}

通过 import * as 就完成了模块整体的导入。

import * as test form ‘./test.js‘;

通过指令 module 也可以达到整体的输入。

module test from ‘test.js‘;

test.getName();

export default

不用关系模块输出了什么,通过 export default 指令就能加载到默认模块,不需要通过 花括号来指定输出的模块,一个模块只能使用 export default 一次

// default 导出

export default function getAge() {}

// 或者写成

function getAge() {}

export default getAge;

// 导入的时候不需要花括号

import test from ‘./test.js‘;

一条import 语句可以同时导入默认方法和其它变量.

import defaultMethod, { otherMethod } from ‘xxx.js‘;

2.6 class命令

如果你用过纯面向对象语言,那么你会对class的语法非常熟悉。

class People {

constructor(name) { //构造函数

this.name = name;

}

sayName() {

console.log(this.name);

}

}

var p = new People("Tom");

p.sayName();

上面定义了一个People类,他有一个属性 name 和一个方法 sayName(),还有一个构造函数;

就像函数有函数声明和函数表达式两种定义方式,类也可以通过类表达式来定义:

let People = class {

constructor(name) { //构造函数

this.name = name;

}

sayName() {

console.log(this.name);

}

}

你可能以为类声明和类表达式的区别在于变量提升的不同。但是事实是无论是类声明还是类表达式的方式来定义,都不会有变量提升。所以下面的写法是错的:

通过关键字 extends 来继承一个类,并且,可以通过 super 关键字来引用父类。

class Student extends People {

constructor(name, grade) { //构造函数

super(name);    //通过 super 调用父类的构造函数的。

this.grade = grade;

}

sayGrade() {

console.log(this.grade);

}

}

上面的例子中我们定义了一个 Student ,他是 People 的子类。

下面我们给 name 属性定义 getter 和 setter

class People {

constructor(name) { //构造函数

this.name = name;

}

get name() {

return this._name.toUpperCase();

}

set name(name) {

this._name = name;

}

sayName() {

console.log(this.name);

}

}

var p = new People("tom");

console.log(p.name);    //TOM

console.log(p._name);    //tom

p.sayName();    //TOM

仔细看上面的例子,搞清楚最后三行分别会输出什么,就明白getter 和 setter该怎么用了。

主要是要区分 this._name 和 this.name 的区别。因为我们定义了 name 的读写器,而没有定义 _name 的读写器,所以访问这两个属性的结果是不同的。

但是要注意一点,不要这样写:

set name(name) {

this.name = name;

}

因为给 this.name 赋值的时候会调用 set name ,这样会导致无限递归直到栈溢出。

通过 static 关键字定义静态方法:

class People {

constructor(name) { //构造函数

this.name = name;

}

sayName() {

console.log(this.name);

}

static formatName(name) {

return name[0].toUpperCase() + name.sustr(1).toLowerCase();

}

}

console.log(People.formatName("tom"));

3.解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。下面是一些使用嵌套数组进行解构的例子。

如果解构不成功,变量的值就等于undefined。

let [foo, [[bar], baz]] = [1, [[2], 3]];

foo // 1

bar // 2

baz // 3

let [x, , y] = [1, 2, 3];//不完全解构

x // 1

y // 3

let [head, ...tail] = [1, 2, 3, 4];

head // 1

tail // [2, 3, 4]

let [x, y, ...z] = [‘a‘];

x // "a"

y // undefined

z // []

解构赋值允许指定默认值。

var [foo = true] = [];

foo // true

[x, y = ‘b‘] = [‘a‘]; // x=‘a‘, y=‘b‘

[x, y = ‘b‘] = [‘a‘, undefined]; // x=‘a‘, y=‘b‘

注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

let [x = 1, y = x] = [];     // x=1; y=1

let [x = 1, y = x] = [2];    // x=2; y=2

let [x = 1, y = x] = [1, 2]; // x=1; y=2

let [x = y, y = 1] = [];     // ReferenceError

解构赋值不仅适用于var命令,也适用于let和const命令。

var [v1, v2, ..., vN ] = array;

let [v1, v2, ..., vN ] = array;

const [v1, v2, ..., vN ] = array;

对于Set结构,也可以使用数组的解构赋值。

let [x, y, z] = new Set(["a", "b", "c"]);

x // "a"

对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

var { foo, bar } = { foo: "aaa", bar: "bbb" };

foo // "aaa"

bar // "bbb"

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

var { bar, foo } = { foo: "aaa", bar: "bbb" };

foo // "aaa"

bar // "bbb"

var { baz } = { foo: "aaa", bar: "bbb" };

baz // undefined

如果变量名与属性名不一致,必须写成下面这样。

var { foo: baz } = { foo: ‘aaa‘, bar: ‘bbb‘ };

baz // "aaa"

let obj = { first: ‘hello‘, last: ‘world‘ };

let { first: f, last: l } = obj;

f // ‘hello‘

l // ‘world‘

这实际上说明,对象的解构赋值是下面形式的简写。

var { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

也就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

var { foo: baz } = { foo: "aaa", bar: "bbb" };

baz // "aaa"

foo // error: foo is not defined

变量的声明和赋值是一体的。对于let和const来说,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错。

let foo;

let {foo} = {foo: 1}; // SyntaxError: Duplicate declaration "foo"

let baz;

let {bar: baz} = {bar: 1}; // SyntaxError: Duplicate declaration "baz"

上面代码中,解构赋值的变量都会重新声明,所以报错了。不过,因为var命令允许重新声明,所以这个错误只会在使用let和const命令时出现。如果没有第二个let命令,上面的代码就不会报错。

let foo;

({foo} = {foo: 1}); // 成功

let baz;

({bar: baz} = {bar: 1}); // 成功

上面代码中,let命令下面一行的圆括号是必须的,否则会报错。因为解析器会将起首的大括号,理解成一个代码块,而不是赋值语句。

和数组一样,解构也可以用于嵌套结构的对象。

var obj = {

p: [

‘Hello‘,

{ y: ‘World‘ }

]

};

var { p: [x, { y }] } = obj;

x // "Hello"

y // "World"

注意,这时p是模式,不是变量,因此不会被赋值。

var node = {

loc: {

start: {

line: 1,

column: 5

}

}

};

var { loc: { start: { line }} } = node;

line // 1

loc  // error: loc is undefined

start // error: start is undefined

默认值生效的条件是,对象的属性值严格等于undefined。

如果要将一个已经声明的变量用于解构赋值,必须非常小心。

// 错误的写法

var x;

{x} = {x: 1};

// SyntaxError: syntax error

上面代码的写法会报错,因为JavaScript引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题。

// 正确的写法

({x} = {x: 1});

由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

var arr = [1, 2, 3];

var {0 : first, [arr.length - 1] : last} = arr;

first // 1

last // 3

字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

const [a, b, c, d, e] = ‘hello‘;

a // "h"

b // "e"

c // "l"

d // "l"

e // "o"

类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

let {length : len} = ‘hello‘;

len // 5

数值和布尔值的解构赋值

解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。

let {toString: s} = 123;

s === Number.prototype.toString // true

let {toString: s} = true;

s === Boolean.prototype.toString // true

上面代码中,数值和布尔值的包装对象都有toString属性,因此变量s都能取到值。

解构赋值的规则是,只要等号右边的值不是对象,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError

let { prop: y } = null; // TypeError

函数参数的解构也可以使用默认值。

function move({x = 0, y = 0} = {}) {

return [x, y];

}

move({x: 3, y: 8}); // [3, 8]

move({x: 3}); // [3, 0]

move({}); // [0, 0]

move(); // [0, 0]

函数move的参数是一个对象,通过对这个对象进行解构,得到变量x和y的值。如果解构失败,x和y等于默认值。

function move({x, y} = { x: 0, y: 0 }) {

return [x, y];

}

move({x: 3, y: 8}); // [3, 8]

move({x: 3}); // [3, undefined]

move({}); // [undefined, undefined]

move(); // [0, 0]

函数move的参数指定默认值,而不是为变量x和y指定默认值,所以会得到与前一种写法不同的结果。

事实上,只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值。

function* fibs() {

var a = 0;

var b = 1;

while (true) {

yield a;

[a, b] = [b, a + b];

}

}

var [first, second, third, fourth, fifth, sixth] = fibs();

sixth // 5

解构赋值用途:

(1)交换变量的值

[x, y] = [y, x];

上面代码交换变量x和y的值,这样的写法不仅简洁,而且易读,语义非常清晰。

(2)从函数返回多个值

函数只能返回一个值,如果要返回多个值,只能将它们放在数组或对象里返回。有了解构赋值,取出这些值就非常方便。

// 返回一个数组

function example() {

return [1, 2, 3];

}

var [a, b, c] = example();

// 返回一个对象

function example() {

return {

foo: 1,

bar: 2

};

}

var { foo, bar } = example();

(3)函数参数的定义

解构赋值可以方便地将一组参数与变量名对应起来。

// 参数是一组有次序的值

function f([x, y, z]) { ... }

f([1, 2, 3]);

// 参数是一组无次序的值

function f({x, y, z}) { ... }

f({z: 3, y: 2, x: 1});

(4)提取JSON数据

解构赋值对提取JSON对象中的数据,尤其有用。

var jsonData = {

id: 42,

status: "OK",

data: [867, 5309]

};

let { id, status, data: number } = jsonData;

console.log(id, status, number);

// 42, "OK", [867, 5309]

上面代码可以快速提取JSON数据的值。

(5)函数参数的默认值

jQuery.ajax = function (url, {

async = true,

beforeSend = function () {},

cache = true,

complete = function () {},

crossDomain = false,

global = true,

// ... more config

}) {

// ... do stuff

};

指定参数的默认值,就避免了在函数体内部再写var foo = config.foo || ‘default foo‘;这样的语句。

(6)遍历Map结构

任何部署了Iterator接口的对象,都可以用for...of循环遍历。Map结构原生支持Iterator接口,配合变量的解构赋值,获取键名和键值就非常方便。

var map = new Map();

map.set(‘first‘, ‘hello‘);

map.set(‘second‘, ‘world‘);

for (let [key, value] of map) {

console.log(key + " is " + value);

}

// first is hello

// second is world

如果只想获取键名,或者只想获取键值,可以写成下面这样。

// 获取键名

for (let [key] of map) {

// ...

}

// 获取键值

for (let [,value] of map) {

// ...

}

(7)输入模块的指定方法

加载模块时,往往需要指定输入那些方法。解构赋值使得输入语句非常清晰。

const { SourceMapConsumer, SourceNode } = require("source-map");

4.编程风格

4.1 采用严格模式:‘use strict‘;

主要有以下限制:

变量必须声明后再使用

函数的参数不能有同名属性,否则报错

不能使用with语句

不能对只读属性赋值,否则报错

不能使用前缀0表示八进制数,否则报错

不能删除不可删除的属性,否则报错

不能删除变量delete prop,会报错,只能删除属性delete global[prop]

eval不会在它的外层作用域引入变量

eval和arguments不能被重新赋值

arguments不会自动反映函数参数的变化

不能使用arguments.callee

不能使用arguments.caller

禁止this指向全局对象

不能使用fn.caller和fn.arguments获取函数调用的堆栈

增加了保留字(比如protected、static和interface)

4.2 let取代var

在块级作用域下,let完全可以取代var,因为两者语义相同,而且let没有副作用。

4.3 全局常量和线程安全

在let和const之间,建议优先使用const,尤其是在全局环境,不应该设置变量,只应设置常量。所有的函数都应该设置为常量。这符合函数式编程思想,有利于将来的分布式运算。

const声明常量还有两个好处,一是阅读代码的人立刻会意识到不应该修改这个值,二是防止了无意间修改变量值所导致的错误。

长远来看,JavaScript可能会有多线程的实现(比如Intel的River Trail那一类的项目),这时let表示的变量,只应出现在单线程运行的代码中,不能是多线程共享的,这样有利于保证线程安全。

4.4 字符串

静态字符串一律使用单引号或反引号,不使用双引号。动态字符串使用反引号。

4.5 解构赋值

使用数组成员对变量赋值时,优先使用解构赋值。

函数的参数如果是对象的成员,优先使用解构赋值。

如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。这样便于以后添加返回值,以及更改返回值的顺序。

4.6 对象

单行定义的对象,最后一个成员不以逗号结尾。多行定义的对象,最后一个成员以逗号结尾。

对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法。

如果对象的属性名是动态的,可以在创造对象的时候,使用属性表达式定义。

另外,对象的属性和方法,尽量采用简洁表达法,这样易于描述和书写。

4.7 数组

使用扩展运算符(...)拷贝数组。

使用Array.from方法,将类似数组的对象转为数组。

4.8 函数

立即执行函数可以写成箭头函数的形式。

那些需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了this。

简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。

所有配置项都应该集中在一个对象,放在最后一个参数,布尔值不可以直接作为参数。

不要在函数体内使用arguments变量,使用rest运算符(...)代替。因为rest运算符显式表明你想要获取参数,而且arguments是一个类似数组的对象,而rest运算符可以提供一个真正的数组。

4.9 Map结构

注意区分Object和Map,只有模拟现实世界的实体对象时,才使用Object。如果只是需要key: value的数据结构,使用Map结构。因为Map有内建的遍历机制。

4.10 Class

总是用Class,取代需要prototype的操作。因为Class的写法更简洁,更易于理解。

使用extends实现继承,因为这样更简单,不会有破坏instanceof运算的危险。

4.11 模块

首先,Module语法是JavaScript模块的标准写法,坚持使用这种写法。使用import取代require。

如果模块只有一个输出值,就使用export default,如果模块有多个输出值,就不使用export default,不要export default与普通的export同时使用。

不要在模块输入中使用通配符。因为这样可以确保你的模块之中,有一个默认输出(export default)。

如果模块默认输出一个对象,对象名的首字母应该大写。

5.网络资源

http://www.w3school.com.cn/js/index.asp

http://es6.ruanyifeng.com/

http://babeljs.io/

时间: 2024-08-09 08:24:17

React-Native_02:语法篇的相关文章

golang学习笔记:golang 语法篇(二)

在语法篇(一)中学习了go中基本的数据类型.变量.常量等组成语言的基本要素,在这一节中将会学习如何将这些元素组织起来,最终写成可以执行的代码. 在这一部分包括: go中的流程控制语句: go中函数的用法: go特殊的错误处理方式: Golang中的流程控制语句 在具体编程的时候免不了需要使用一些特殊的语句实现某些功能,比如使用循环语句来进行迭代,使用选择语句控制程序的执行方式等.这些语句在任何一门程序设计语言 中都会有支持,golang中除了支持常用的循环,条件选择语句以外,还支持跳转语句,下面

Flex 布局教程:语法篇

注:最近研究整理swiper时,发现了Flex这个好东西,好东西! 原文地址:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html Flex 布局教程:语法篇 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C提出了一种新的方案----Flex布局,可以简

react component 语法报错解决

React es6语法 class Counter extends Component { static propTypes = { 报错. 两个解决方案: 1.等号改为冒号,但是看着别扭 2.yarn add babel-preset-stage-0 { "presets": ["react", "es2015", "stage-0"] }

程序猿二三事之Java基础--Java SE 5增加的特性--语法篇(一)

程序猿二三事之Java基础–Java SE 5增加的特性–语法篇(一) [ TOC ] 为什么是Java SE 5? 目前已经到了JDK-8u74了,JDK7的主版本已经于2015年4月停止公开更新. 那为什么还要来说Java/JDK5呢? Java SE在1.4(2002)趋于成熟,随着越来越多应用于开发企业应用,许多框架诞生于这个时期或走向成熟. Java SE 5.0的发布(2004)在语法层面增加了很多特性,让开发更高效,代码更整洁. 自动装箱/拆箱.泛型.注解.for循环增强.枚举.可

【转】正则表达式教程——语法篇

正则表达式教程--语法篇 工具 原文地址:https://www.cnblogs.com/tanghuimin0713/p/8718983.html

Flex 布局教程:语法篇 【转】

Flex 布局教程:语法篇 作者: 阮一峰 日期: 2015年7月10日 原文:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html 网页布局(layout)是 CSS 的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C 提出了一种新的方案----Flex 布局,可以简便.完整.响应式

iOS开发——语法篇OC篇&amp;高级语法精讲二

Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发.下面通过分析Apple开源的Runtime代码(我使用的版本是objc4-646.tar)来深入理解Objective-C的Runtime机制. Runtime数据结构 在Objective-C中,使用[receiver message]语法并不会马上执行receiver对象的message方

转:阮一峰Flex 布局教程:语法篇

作者: 阮一峰 日期: 2015年7月10日 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C提出了一种新的方案----Flex布局,可以简便.完整.响应式地实现各种页面布局.目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能. Flex布局将成为未来布局的首选方案.本文介绍它的语法,下一

React JSX语法说明

什么是JSX? 在用React写组件的时候,通常会用到JSX语法,粗看上去,像是在Javascript代码里直接写起了XML标签,实质上这只是一个语法糖,每一个XML标签都会被JSX转换工具转换成纯Javascript代码,当然你想直接使用纯Javascript代码写也是可以的,只是利用JSX,组件的结构和组件之间的关系看上去更加清晰. var MyComponent = React.createClass({/*...*/}); var myElement = <MyComponent som

CSDN markdown 编辑器 第三篇 基本语法篇

这一篇准备抄一下help文档,另外加一些自己的解释.这一篇里不讲UML和LaTEX. 准备抽两个篇专门讲一下. 1. 标题与字号 markdown字号太少了,觉得应该再加些. 在文字写书写不同数量的#可以完成不同的标题,如下: # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 一级标题 二级标题 三级标题 四级标题 五级标题 六级标题 这里的需要注意的是 #[空格]标题 一定要有空格 等号及减号也可以进行标题的书写,不过只能书写二级