窗边的扁豆


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

MySql索引

发表于 2017-07-18 | 分类于 MySql

MySql索引

[TOC]

神马是MySql索引

​ 数据库索引是一种数据结构,目的是提高表的操作速度。要创建的索引,应当认为哪列将用于使SQL查询,创建对这些列的一个或多个索引。实际上,索引也是表,其中保存主键或索引字段的指针并指向每个记录到实际的表的类型。

​ 索引一方面可以提高数据的检索速度,不过另一方面过多的索引会降低表的gen更新速度,(因为在更新表的同时也会更新索引。)

索引的基本用法

  1. 创建与修改普通索引

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    CREATE INDEX indexName ON mytable(username(length));
    //创建表的时候直接指定
    CREATE TABLE mytable(
    ID INT NOT NULL,
    username VARCHAR(16) NOT NULL,
    INDEX [indexName] (username(length))
    );
    //修改索引
    ALTER mytable ADD INDEX [indexName] ON (username(length))
    //删除索引
    DROP INDEX [indexName] ON mytable;
  2. 创建与修改复合索引

    复合索引是在多个字段上创建的索引。复合索引遵守“最左前缀”原则,即在查询条件中使用了复合索引的第一个字段,索引才会被使用。因此,在复合索引中索引列的顺序至关重要。

    1
    2
    3
    create index index_name on tbl_name(index_col_name,...);
    //修改索引
    alter table tbl_name add index index_name on (index_col_name,...);
  3. 创建与修改唯一索引

    唯一索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE UNIQUE INDEX indexName ON mytable(username(length))
    //创建表的时候直接指定
    CREATE TABLE mytable(
    ID INT NOT NULL,
    username VARCHAR(16) NOT NULL,
    UNIQUE [indexName] (username(length))
    );
    //修改索引
    ALTER table mytable ADD UNIQUE [indexName] (username(length))
  4. 创建与修改主键索引

    主键索引值必须是唯一的,且不能为NULL。(默认创建主键都会为该列创建索引)

    1
    2
    3
    ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)
    //删除索引
    ALTER TABLE testalter_tbl DROP PRIMARY KEY;
  5. 创建与修改全文索引

    它能够利用「分词技术「等多种算法智能分析出文本文字中关键字词的频率及重要性,然后按照一定的算法规则智能地筛选出我们想要的搜索结果。

    1
    2
    3
    4
    5
    6
    7
    8
    CREATE TABLE article (
    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
    title VARCHAR(200),
    content TEXT,
    FULLTEXT (title, content) --在title和content列上创建全文索引
    );
    //修改索引
    ALTER TABLE article ADD FULLTEXT INDEX fulltext_article (title, content)

    如何使用全文索引

    1
    2
    //在article表的title和content列中全文检索指定的查询字符串
    SELECT * FROM article WHERE MATCH(title, content) AGAINST('查询字符串')

    MySQL自带的全文索引只能对英文进行全文检索,目前无法对中文进行全文检索。如果需要对包含中文在内的文本数据进行全文检索,我们需要采用Sphinx(斯芬克斯)/Coreseek技术来处理中文。

使用索引的注意事项

  • 不要在列上进行运算或者函数

    在索引列上进行运算或使用函数会导致索引失效

    1
    select * from user where YEAR(birthday)<1990 and code="">
  • 不要为多个列创建索引

    为多个列创建独立的索引,大部分并不能提高MySQL的查询性能。因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。

  • 索引不会包含有NULL值的列

    只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

  • 范围查询对多列查询的影响

    如果查询中的某个列有范围查询,则其右边所有列都无法使用索引优化查找。

    1
    where age>10 and age<90 and name="lianggzone" >

    这是因为age是范围查询,导致多列索引t_index(age,name),无法用到name索引。

    ​

Koa2的基本使用

发表于 2017-07-17 | 分类于 node.js

Koa2的基本使用

[TOC]

简介

  • koa2完全使用Promise并配合async来实现异步。但代码看起爱像是同步的。

入门程序

  • 创建app.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 导入koa,和koa 1.x不同,在koa2中,我们导入的是一个class,因此用大写的Koa表示:
    const Koa = require('koa');
    // 创建一个Koa对象表示web app本身:
    const app = new Koa();
    // 对于任何请求,app将调用该异步函数处理请求:
    //参数ctx是由koa传入的封装了request和response的变量,我们可以通过它访问request和response,next是koa传入的将要处理的下一个异步函数。
    app.use(async (ctx, next) => {
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, koa2!</h1>';
    });
    // 在端口3000监听:
    app.listen(3000);
    console.log('app started at port 3000...');

    由async标记的函数称为异步函数,在异步函数中,可以用await调用另一个异步函数。

  • koa把很多async函数组成一个处理链,每个async函数都可以做一些自己的事情,然后用await next()来调用下一个async函数。我们把每个async函数称为middleware,这些middleware可以组合起来,完成很多有用的功能。app.use()的顺序决定了middleware的顺序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    app.use(async (ctx, next) => {
    console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
    await next(); // 调用下一个middleware
    });
    app.use(async (ctx, next) => {
    const start = new Date().getTime(); // 当前时间
    await next(); // 调用下一个middleware
    const ms = new Date().getTime() - start; // 耗费时间
    console.log(`Time: ${ms}ms`); // 打印耗费时间
    });
    app.use(async (ctx, next) => {
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, koa2!</h1>';
    });

    如果没有调用await next(); 那么后面的middleware都不会执行。(可以利用这个进行用户权限判定)

创建url映射

  • 将不同的url映射到不同的函数,通过koa-router实现。

  • 处理get请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    const Koa = require('koa');
    // 注意require('koa-router')返回的是函数:
    const router = require('koa-router')();
    const app = new Koa();
    // log request URL:
    app.use(async (ctx, next) => {
    console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
    await next();
    });
    // 注册一个get函数,并注明映射的url
    router.get('/hello/:name', async (ctx, next) => {
    var name = ctx.params.name;
    ctx.response.body = `<h1>Hello, ${name}!</h1>`;
    });
    router.get('/', async (ctx, next) => {
    ctx.response.body = '<h1>Index</h1>';
    });
    // add router middleware:
    app.use(router.routes());
    app.listen(3000);
    console.log('app started at port 3000...');
  • 处理post请求

    ​ post请求通常会发送一个表单,或者JSON,它作为request的body发送,但无论是Node.js提供的原始request对象,还是koa提供的request对象,都不提供解析request的body的功能!

    ​ 所以,我们又需要引入另一个middleware(koa-bodyparser)来解析原始request请求,然后,把解析后的参数,绑定到ctx.request.body中。

    1. 在package.json中添加依赖

      1
      "koa-bodyparser": "3.2.0"
    2. 解析post请求

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      //引入koa-bodyparser
      const bodyParser = require('koa-bodyparser');
      //koa-bodyparser必须在router之前被注册到app对象上。
      app.use(bodyParser());
      router.post('/signin', async (ctx, next) => {
      //如果该字段不存在,默认值设置为''。
      var
      name = ctx.request.body.name || '',
      password = ctx.request.body.password || '';
      console.log(`signin with name: ${name}, password: ${password}`);
      if (name === 'koa' && password === '12345') {
      ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
      } else {
      ctx.response.body = `<h1>Login failed!</h1>
      <p><a href="/">Try again</a></p>`;
      }
      });
      app.use(router.routes());
      app.listen(3000);
      console.log('app started at port 3000...');
  • 封装一个简单的url映射框架

    我们将处理url映射的js按照功能划分,并统一放在controller包中。

    1. 新建controller包,在其内新建user.js

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      var fn_signin = async (ctx, next) => {
      var
      name = ctx.request.body.name || '',
      password = ctx.request.body.password || '';
      console.log(`signin with name: ${name}, password: ${password}`);
      if (name === 'koa' && password === '12345') {
      ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
      } else {
      ctx.response.body = `<h1>Login failed!</h1>
      <p><a href="/">Try again</a></p>`;
      }
      };
      //将signin方法暴露出去
      module.exports = {
      'POST /signin': fn_signin
      };
    2. 新建controller.js负责扫描cintroller包下的js文件,并为其注册到router

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      const fs = require('fs');
      function addMapping(router, mapping) {
      for (var url in mapping) {
      if (url.startsWith('GET ')) {
      var path = url.substring(4);
      router.get(path, mapping[url]);
      console.log(`register URL mapping: GET ${path}`);
      } else if (url.startsWith('POST ')) {
      var path = url.substring(5);
      router.post(path, mapping[url]);
      console.log(`register URL mapping: POST ${path}`);
      } else {
      console.log(`invalid URL: ${url}`);
      }
      }
      }
      function addControllers(router,dir) {
      var files = fs.readdirSync(__dirname + dir+'');
      var js_files = files.filter((f) => {
      return f.endsWith('.js');
      });
      for (var f of js_files) {
      console.log(`process controller: ${f}...`);
      let mapping = require(__dirname + '/controllers/' + f);
      addMapping(router, mapping);
      }
      }
      module.exports = function (dir) {
      let
      controllers_dir = dir || 'controllers', // 如果不传参数,扫描目录默认为'controllers'
      router = require('koa-router')();
      addControllers(router, controllers_dir);
      return router.routes();
      };
    3. 新建app.js,调用controller.js提供的方法

      1
      2
      3
      4
      5
      6
      7
      // 导入controller middleware:
      const controller = require('./controller');
      ...
      // 使用middleware:
      app.use(controller());

      ​

Node中的模块

发表于 2017-07-17 | 分类于 node.js

Node中的模块

[TOC]

####常用内置对象

  • global

    而在Node.js环境中,有唯一的全局对象,叫global,这个对象的属性和方法也和浏览器环境的window不同

  • process

    代表当前Node.js进程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    > process.version;
    'v5.2.0'
    > process.platform;
    'darwin'
    > process.arch;
    'x64'
    > process.cwd(); //返回当前工作目录
    '/Users/michael'
    > process.chdir('/private/tmp'); // 切换当前工作目录
    undefined
    > process.cwd();
    '/private/tmp'

常用内置模块

  • 文件系统模块(服务端都要使用异步方法)

    1. 异步读取文本文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      'use strict'
      var fs=require('fs');
      //在同级目录下的文本文件,当正常读取时,err参数为null,data参数为读取到的String。当读取发生错误时,err参数代表一个错误对象,data为undefined
      fs.readFile('hello.txt','utf-8',function(err,data){
      if(err){
      console.log(err);
      }
      else{
      console.log(data);
      }
      })
    2. 异步读取二进制文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      'use strict';
      var fs = require('fs');
      //当读取二进制文件时,不传入文件编码时,回调函数的data参数将返回一个Buffer对象。在Node.js中,Buffer对象就是一个包含零个或任意个字节的数组(注意和Array不同)。
      fs.readFile('sample.png', function (err, data) {
      if (err) {
      console.log(err);
      } else {
      console.log(data);
      console.log(data.length + ' bytes');
      }
      });

      Buffer对象与String对象之间的转化

      1
      2
      3
      4
      5
      6
      // Buffer -> String
      var text = data.toString('utf-8');
      console.log(text);
      // String -> Buffer
      var buf = new Buffer(text, 'utf-8');
      console.log(buf);
    3. 同步读取文件

      1
      2
      3
      4
      5
      'use strict';
      var fs = require('fs');
      //不接受回调函数,直接函数返回结果
      var data = fs.readFileSync('sample.txt', 'utf-8');
      console.log(data);
    4. 异步写文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      'use strict';
      var fs = require('fs');
      var data = 'Hello, Node.js';
      //如果传入的数据是String,默认按UTF-8编码写入文本文件,如果传入的参数是Buffer,则写入的是二进制文件。回调函数由于只关心成功与否,因此只需要一个err参数。
      fs.writeFile('output.txt', data, function (err) {
      if (err) {
      console.log(err);
      } else {
      console.log('ok.');
      }
      });
    5. 同步写文件

      1
      2
      3
      4
      5
      6
      'use strict';
      var fs = require('fs');
      var data = 'Hello, Node.js';
      fs.writeFileSync('output.txt', data);
    6. 通过stat获取文件的基本信息

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      'use strict';
      var fs = require('fs');
      fs.stat('sample.txt', function (err, stat) {
      if (err) {
      console.log(err);
      } else {
      // 是否是文件:
      console.log('isFile: ' + stat.isFile());
      // 是否是目录:
      console.log('isDirectory: ' + stat.isDirectory());
      if (stat.isFile()) {
      // 文件大小:
      console.log('size: ' + stat.size);
      // 创建时间, Date对象:
      console.log('birth time: ' + stat.birthtime);
      // 修改时间, Date对象:
      console.log('modified time: ' + stat.mtime);
      }
      }
      });
  • Stream模块

    流是一种抽象的数据结构。特点是数据是有序的,而且必须依次读取,或者依次写入,不能像Array那样随机定位。

    1. 从文本流读取文本内容

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      'use strict';
      var fs = require('fs');
      // 打开一个流:
      var rs = fs.createReadStream('hello.txt', 'utf-8');
      //data事件可能会有多次,每次的data只是一部分的数据
      rs.on('data', function (data) {
      console.log('DATA:')
      console.log(data);
      });
      rs.on('end', function () {
      console.log('END');
      });
      rs.on('error', function (err) {
      console.log('ERROR: ' + err);
      });
    2. 以流的形式写入文件

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      'use strict';
      var fs = require('fs');
      var ws1 = fs.createWriteStream('output1.txt', 'utf-8');
      ws1.write('使用Stream写入文本数据...\n');
      ws1.write('END.');
      ws1.end();
      var ws2 = fs.createWriteStream('output2.txt');
      ws2.write(new Buffer('使用Stream写入二进制数据...\n', 'utf-8'));
      ws2.write(new Buffer('END.', 'utf-8'));
      ws2.end();
    3. 通过pipe快速复制文件

      pipe()把一个文件流和另一个文件流串起来,这样源文件的所有数据就自动写入到目标文件里了

      1
      2
      3
      4
      5
      6
      7
      8
      'use strict';
      var fs = require('fs');
      var rs = fs.createReadStream('sample.txt');
      var ws = fs.createWriteStream('copied.txt');
      rs.pipe(ws);
  • Http网络模块

    1. 接受网络请求

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      'use strict';
      // 导入http模块:
      var http = require('http');
      // 创建http server,并传入回调函数:
      var server = http.createServer(function (request, response) {
      // 回调函数接收request和response对象,
      // 获得HTTP请求的method和url:
      console.log(request.method + ': ' + request.url);
      // 将HTTP响应200写入response, 同时设置Content-Type: text/html:
      response.writeHead(200, {'Content-Type': 'text/html'});
      // 将HTTP响应的HTML内容写入response:
      response.end('<h1>Hello world!</h1>');
      });
      // 让服务器监听8080端口:
      server.listen(8080);
      console.log('Server is running at http://127.0.0.1:8080/');

      ​

    ​

Node.js入门

发表于 2017-07-17 | 分类于 node.js

Node.js入门

[TOC]

简介

​ 简单来说,Node.js 就是运行在服务端的 JavaScript。是一个基于Chrome JavaScript 运行时建立的一个平台,是一个事件驱动I/O服务端JavaScript环境。

创建第一个服务器应用

​ 一般而言,创建一个node.js应用需要以下步骤:

  1. 引入 required 模块:我们可以使用 require 指令来载入 Node.js 模块。

    1
    var http=require("http");
  2. 创建服务器:服务器可以监听客户端的请求,类似于 Apache 、Nginx 等 HTTP 服务器。

    1
    2
    3
    4
    http.createServer(function (request,response){
    response.writeHead(200,{'content-type':'text/plain'});
    response.end("hello world\n");
    }).listen(8888);
  3. 接收请求与响应请求 服务器很容易创建,客户端可以使用浏览器或终端发送 HTTP 请求,服务器接收请求后返回响应数据。

    在命令行中运行js文件。

    1
    node server.js

    然后就相当于启动了一个web服务器,直接在浏览器中即可访问到接口。

    这里写图片描述

    ​

模块的基本概念

​ 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式。在Node环境中,一个.js文件就称之为一个模块(module)。

1
2
3
4
5
6
7
8
9
'use strict';
var s = 'Hello';
function greet(name) {
console.log(s + ', ' + name + '!');
}
//把函数greet作为模块的输出暴露出去,这样其他模块就可以使用greet函数了。
module.exports = greet;

在其他js文件中通过以下办法引用模块

1
2
3
4
5
6
7
8
'use strict';
// 引入hello模块:
var greet = require('./hello');
var s = 'Michael';
greet(s); // Hello, Michael!d

node查找模块的顺序依次为:内置模块、全局模块和当前模块;

​

了解模块的原理

  • 这种模块加载机制被称为CommonJS规范。在这个规范下,每个.js文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突。那么node是如何做到命名不冲突的呢?这里就需要使用到js的特性了。这里的 node将我们编写的js文件通过函数包裹起来,将其声明的全局变量都变成了局部变量。从未防止了命名冲突的问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //原本代码
    var s = 'Hello';
    var name = 'world';
    console.log(s + ' ' + name + '!');
    //包装后的代码
    (function () {
    // 读取的hello.js代码:
    var s = 'Hello';
    var name = 'world';
    console.log(s + ' ' + name + '!');
    // hello.js代码结束
    })();

    通过这种方法从而实现了模块的隔离。

  • node是如何将模块暴露给其他js文件呢

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 准备module对象:
    var module = {
    id: 'hello',
    exports: {}
    };
    var load = function (module) {
    // 读取的hello.js代码:
    function greet(name) {
    console.log('Hello, ' + name + '!');
    }
    module.exports = greet;
    // hello.js代码结束
    return module.exports;
    };
    var exported = load(module);
    // 保存module:
    save(module, exported);
    1. 变量module是Node在加载js文件前准备的一个变量,并将其传入加载函数,我们在hello.js中可以直接使用变量module原因就在于它实际上是函数的一个参数:
    2. 通过把参数module传递给load()函数,hello.js就顺利地把一个变量传递给了Node执行环境,Node会把module变量保存到某个地方。
    3. 由于Node保存了所有导入的module,当我们用require()获取module时,Node找到对应的module,把这个module的exports变量返回,

    ​

JavaScrript单引号与双引号的区别

发表于 2017-07-14 | 分类于 javascript

JavaScrript单引号与双引号的区别

[TOC]

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var str = 'This is Jack';
var str2 = "This is Tom";
var str3 = 'This is "Rose"';
var str4 = "This is 'LiLi'";
var str5 = "This is \"Sun\"";
var str6 = 'This is \'Mary\'';
var str7 = "This is \'Lucy\'";
var str8 = 'This is \"Rooney\"';
var str9 = 'This is \\Ronaldo\\';
console.log(str);
console.log(str2);
console.log(str3);
console.log(str4);
console.log(str5);
console.log(str6);
console.log(str7);
console.log(str8);
console.log(str9);
//显示结果
This is Jack
This is Tom
This is "Rose"
This is 'LiLi'
This is "Sun"
This is 'Mary'
This is 'Lucy'
This is "Rooney"
This is \Ronaldo\
  1. 只使用字符的字符串,单引号和双引号没有区别

  2. 在单引号包括的字符串中可以直接用双引号,在双引号包括的字符串中可以直接用单引号

  3. 如果在双引号包括的字符串中用双引号,需要用反斜杠转义,注意是”\” ;同样在单引号包括的字符串中用单引号,也需要转义

  4. 如果要用反斜杠,则输入‘\’

    ​

JavaScript的跨域请求

发表于 2017-07-12 | 分类于 javascript

JavaScript的跨域请求

[TOC]

神马是跨域请求

​ 因为浏览器的同源策略,默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致。

也就是说,请求ajax的url,域名要相同(www.example.com和example.com不同),协议要相同(http和https不同),端口号要相同(默认是:80端口,它和:8080就不同)。

解决方法

  1. 通过在同源域名下架设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器。然后让代理服务器帮助我们完成请求。

  2. 通过JSONP,它有个限制,只能用GET请求,并且要求返回JavaScript。这种方式跨域实际上是利用了浏览器允许跨域引用JavaScript资源:

  3. 通过CORS进行跨域请求。

    cros是提出的新的跨域策略:

    这里写图片描述

    Origin表示本域,也就是浏览器当前页面的域。当JavaScript向外域(如sina.com)发起请求后,浏览器收到响应后,首先检查Access-Control-Allow-Origin是否包含本域(或者*),如果是,则此次跨域请求成功,如果不是,则请求失败,JavaScript将无法获取到响应的任何数据。

    可见,跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin,决定权始终在对方手中。

    ​

JavaScript的标准对象

发表于 2017-07-11 | 分类于 javascript

JavaScript的标准对象

[TOC]

Date

  • 在JavaScript中,Date对象用来表示日期和时间。

  • 常用api

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var now = new Date();
    now; // Wed Jun 24 2015 19:49:22 GMT+0800 (CST)
    now.getFullYear(); // 2015, 年份
    now.getMonth(); // 5, 月份,注意月份范围是0~11,5表示六月
    now.getDate(); // 24, 表示24号
    now.getDay(); // 3, 表示星期三
    now.getHours(); // 19, 24小时制
    now.getMinutes(); // 49, 分钟
    now.getSeconds(); // 22, 秒
    now.getMilliseconds(); // 875, 毫秒数
    now.getTime(); // 1435146562875, 以number形式表示的时间戳
  • 创建一个指定的时间

    1
    2
    var d = new Date(2015, 5, 19, 20, 15, 30, 123);
    //由于设计者的脑抽,所以这里的5代表6月份,月份从0开始的

正则表达式

  • js中的正则表达式

    1
    2
    var re1 = /ABC\-001/; //直接通过/正则表达式/格式创建
    var re2 = new RegExp('ABC\\-001'); //通过创建RegExp对象
  • 常用功能

    1. 切分字符串

      1
      'a b c'.split(/\s+/); // ['a', 'b', 'c']
    2. 判断是否匹配

      1
      2
      3
      4
      var re = /^\d{3}\-\d{3,8}$/;
      re.test('010-12345'); // true
      re.test('010-1234x'); // false
      re.test('010 12345'); // false
    3. 分组(即提取子串)

      1
      2
      3
      4
      ///^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:
      var re = /^(\d{3})-(\d{3,8})$/;
      re.exec('010-12345'); // ['010-12345', '010', '12345']
      re.exec('010 12345'); // null
    4. 全局搜索

      通过全局标志符号说明是全局搜索。

      1
      2
      3
      var r1 = /test/g;
      // 等价于:
      var r2 = new RegExp('test', 'g');

      进行全局搜索

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      var s = 'JavaScript, VBScript, JScript and ECMAScript';
      var re=/[a-zA-Z]+Script/g;
      // 使用全局匹配:
      re.exec(s); // ['JavaScript']
      re.lastIndex; // 10
      re.exec(s); // ['VBScript']
      re.lastIndex; // 20
      re.exec(s); // ['JScript']
      re.lastIndex; // 29
      re.exec(s); // ['ECMAScript']
      re.lastIndex; // 44
      re.exec(s); // null,直到结束仍没有匹配到

      正则表达式还可以指定i标志,表示忽略大小写,m标志,表示执行多行匹配。

JavaScript中的json

  • 序列化为json

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
    };
    //普通转化
    JSON.stringify(xiaoming);
    //筛选转化,第二个参数代表输出指定的属性
    JSON.stringify(xiaoming, ['name', 'skills'], ' ');
    //通过函数预处理转化
    function convert(key, value) {
    if (typeof value === 'string') {
    return value.toUpperCase();
    }
    return value;
    }
    JSON.stringify(xiaoming, convert, ' ');
  • 反序列化为对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //普通转化
    JSON.parse('{"name":"小明","age":14}'); // Object {name: '小明', age: 14}
    //加强转化
    JSON.parse('{"name":"小明","age":14}', function (key, value) {
    // 把number * 2:
    if (key === 'name') {
    return value + '同学';
    }
    return value;
    }); // Object {name: '小明同学', age: 14}

    ​

JQuery的扩展

发表于 2017-07-11 | 分类于 jquery

JQuery的扩展

[TOC]

  1. 给jQuery对象绑定一个新方法是通过扩展$.fn对象

    1
    2
    3
    4
    5
    6
    $.fn.hello() = function () {
    // this已绑定为当前jQuery对象:
    this.css('backgroundColor', '#fffceb').css('color', '#d85030');
    return this;
    }
    //函数内部的this在调用时被绑定为jQuery对象,所以函数内部代码可以正常调用所有jQuery对象的方法。

    返回的时候仍然要返回this,保证返回的对象仍然支持链式调用。

  2. 同时我们可以给我们自定义的函数增加参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $.fn.highlight2 = function (options) {
    // 要考虑到各种情况:
    // options为undefined
    // options只有部分key
    var bgcolor = options && options.backgroundColor || '#fffceb';
    var color = options && options.color || '#d85030';
    this.css('backgroundColor', bgcolor).css('color', color);
    return this;
    }

    当然这种考虑各种情况实在有些麻烦,所以JQuery为我们提供了更好的办法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 把默认值和用户传入的options合并到对象{}中并返回:
    var opts = $.extend({}, {
    backgroundColor: '#00a8e6',
    color: '#ffffff'
    }, options);
    //它把多个object对象的属性合并到第一个target对象中,遇到同名属性,总是使用靠后的对象的值,也就是越往后优先级越高
    $.fn.highlight = function (options) {
    // 合并默认值和用户设定值:
    var opts = $.extend({}, $.fn.highlight.defaults, options);
    this.css('backgroundColor', opts.backgroundColor).css('color', opts.color);
    return this;
    }
    // 设定默认值:
    $.fn.highlight.defaults = {
    color: '#d85030',
    backgroundColor: '#fff8de'
    }

    ​

JQuery对DOM的操作

发表于 2017-07-11 | 分类于 jquery

JQuery对DOM的操作

[TOC]

JQuery简介

  • $是著名的jQuery符号。

    实际上,jQuery把所有功能全部封装在一个全局变量jQuery中,而$也是一个合法的变量名,它是变量jQuery的别名:

    1
    2
    3
    4
    window.jQuery; // jQuery(selector, context)
    window.$; // jQuery(selector, context)
    $ === jQuery; // true
    typeof($); // 'function'

    $本质上就是一个函数,但是函数也是对象,于是$除了可以直接调用外,也可以有很多其他属性。

JQuery的选择器

  1. 通过id查找

    1
    2
    // 查找<div id="abc">:
    var div = $('#abc'); //返回的对象是jQuery对象,jQuery对象类似数组,它的每个元素都是一个引用了DOM节点的对象。

    获取到jquery对象之后即可获取dom对象。

    1
    2
    3
    var div = $('#abc'); // jQuery对象
    var divDom = div.get(0); // 假设存在div,获取第1个DOM元素
    var another = $(divDom); // 重新把DOM包装为jQuery对象
  2. 通过标签查找

    1
    2
    var ps = $('p'); // 返回所有<p>节点
    ps.length; // 数一数页面有多少个<p>节点
  3. 通过class查找

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var a = $('.red'); // 所有节点包含`class="red"`都将返回
    // 例如:
    // <div class="red">...</div>
    // <p class="green red">...</p>
    //查找多个class属性的dom
    var a = $('.red.green'); // 注意没有空格!
    // 符合条件的节点:
    // <div class="red green">...</div>
    // <div class="blue green red">...</div>
  4. 通过属性查找

    1
    2
    3
    var email = $('[name=email]'); // 找出<??? name="email">
    var passwordInput = $('[type=password]'); // 找出<??? type="password">
    var a = $('[items="A B"]'); // 找出<??? items="A B">
  5. 组合查找

    1
    var emailInput = $('input[name=email]'); // 不会找出<div name="email">
  • 层级选择器

    首先要定位父节点,才能选择相应的子节点,这样避免了页面其他不相关的元素,缩小了选择范围。

    如果两个DOM元素具有层级关系(只要是包涵关系都是层级关系),就可以用$('ancestor descendant')来选择,层级之间用空格隔开:

    1
    2
    3
    4
    5
    6
    7
    8
    <!-- HTML结构 -->
    <div class="testing">
    <ul class="lang">
    <li class="lang-javascript">JavaScript</li>
    <li class="lang-python">Python</li>
    <li class="lang-lua">Lua</li>
    </ul>
    </div>
    1
    2
    $('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
    $('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
  • 父子选择器

    两个元素必须是父子关系才行(直接包涵不能隔代)。

    1
    2
    $('ul.lang>li.lang-javascript'); // 可以选出[<li class="lang-javascript">JavaScript</li>]
    $('div.testing>li.lang-javascript'); // [], 无法选出,因为<div>和<li>不构成父子关系
  • 过滤器

    1
    2
    3
    4
    5
    6
    7
    $('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点
    $('ul.lang li:first-child'); // 仅选出JavaScript
    $('ul.lang li:last-child'); // 仅选出Lua
    $('ul.lang li:nth-child(2)'); // 选出第N个元素,N从1开始
    $('ul.lang li:nth-child(even)'); // 选出序号为偶数的元素
    $('ul.lang li:nth-child(odd)'); // 选出序号为奇数的元素

查找与过滤

  • 查找

    当我们那个某个dom的jquery对象之后,我们可以通过这个对象进行纵向或者横向查找它的兄弟,父子节点。

    1
    2
    3
    4
    5
    6
    7
    8
    <!-- HTML结构 -->
    <ul class="lang">
    <li class="js dy">JavaScript</li>
    <li class="dy">Python</li>
    <li id="swift">Swift</li>
    <li class="dy">Scheme</li>
    <li name="haskell">Haskell</li>
    </ul>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //通过find查找子节点
    var ul = $('ul.lang'); // 获得<ul>
    var dy = ul.find('.dy'); // 获得JavaScript, Python, Scheme
    var swf = ul.find('#swift'); // 获得Swift
    var hsk = ul.find('[name=haskell]'); // 获得Haskell
    //获取父节点
    var swf = $('#swift'); // 获得Swift
    var parent = swf.parent(); // 获得Swift的上层节点<ul>
    var a = swf.parent('div.red'); // 从Swift的父节点开始向上查找,直到找到某个符合条件的节点并返回
    //查找兄弟节点
    var swift = $('#swift');
    swift.next(); // Scheme
    swift.next('[name=haskell]'); // Haskell,因为Haskell是后续第一个符合选择器条件的节点
    swift.prev(); // Python
    swift.prev('.js'); // JavaScript,因为JavaScript是往前第一个符合选择器条件的节点
  • 过滤

    1. 通过filter过滤dom

      1
      2
      3
      4
      5
      6
      7
      var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
      var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme
      var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
      langs.filter(function () {
      return this.innerHTML.indexOf('S') === 0; // 这里的this代表dom对象
      }); // 拿到Swift, Scheme

操作DOM

  • 修改dom的内容

    jQuery对象的text()和html()方法分别获取节点的文本和原始HTML文本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <!-- HTML结构 -->
    <ul id="test-ul">
    <li class="js">JavaScript</li>
    <li name="book">Java &amp; JavaScript</li>
    </ul>
    <script>
    $('#test-ul li[name=book]').text(); // 'Java & JavaScript'
    $('#test-ul li[name=book]').html(); // 'Java &amp; JavaScript'
    </script>

    无参数调用text()是获取文本,传入参数就变成设置文本,HTML也是类似操作,

    1
    $('#test-ul li[name=book]').text('你好');

    由于jquery对象包含了可能不只一个对象,所以它的方法会作用在每一个dom对象上,即使没有对象也不会报错。

  • 添加新的dom

    通过append方法可以添加dom,对于之前html页面:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var ul = $('#test-ul');//拿到父节点的对象
    ul.append('<li><span>Haskell</span></li>'); //添加dom对象
    // 创建DOM对象:
    var ps = document.createElement('li');
    ps.innerHTML = '<span>Pascal</span>';
    // 添加DOM对象:
    ul.append(ps);
    // 添加jQuery对象:不过会先删除原有的对象
    ul.append($('.js'));
    // 添加函数对象:
    ul.append(function (index, html) {
    return '<li><span>Language - ' + index + '</span></li>';
    });
  • 删除节点

    1
    2
    var li = $('#test-ul>li');
    li.remove(); // 所有<li>全被删除

    ​

JQuery的ajax

发表于 2017-07-10 | 分类于 jquery

JQuery的ajax

[TOC]

  • jQuery在全局对象jQuery(也就是$)绑定了ajax()函数,可以处理AJAX请求。ajax(url, settings)函数需要接收一个URL和一个可选的settings对象,

  • Get请求

    1
    2
    3
    4
    5
    var jqxhr = $.get('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
    });
    //第二个参数代表了请求参数,直接被加到请求url后面
  • POST请求(传入的第二个参数默认被序列化为application/x-www-form-urlencoded:)

    1
    2
    3
    4
    var jqxhr = $.post('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
    });
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    * 直接获取json获取
    ```javascript
    var jqxhr = $.getJSON('/path/to/resource', {
    name: 'Bob Lee',
    check: 1
    }).done(function (data) {
    // data已经被解析为JSON对象了
    }).fail(function (xhr, status) {
    ajaxLog('失败: ' + xhr.status + ', 原因: ' + status);
    }).always(function () {
    ajaxLog('请求完成: 无论成功或失败都会调用');
    });;

    ​

123
forever_zs

forever_zs

26 日志
15 分类
39 标签
GitHub Twitter 微博 豆瓣 知乎
© 2017 forever_zs
由 Hexo 强力驱动
主题 - NexT.Pisces