标签javascript

Javascript中的函数

函数的定义

  1.  var foo = fucntion(a, b) {}; //函数表达式
  2. function foo(a, b) {}; //函数声明
  3. var foo = new Function(“a”, “b”, “return false”); //不推荐

对于函数声明,可以在声明之前调用该函数;而对于函数表达式,不可以在表达式之前调用该函数。

函数的属性

  • this: 引用的是函数执行的环境对象,全局作用域中的this引用的是window对象
  • arguments: 保存函数参数的数组
  • arguments.callee: 指向该函数的指针
  • caller: 函数的调用者
  • length: 函数希望接收到的命名参数的个数

函数的方法

  • call(obj, arg1, arg2…)  //设置函数的运行环境(改变this的值)
  • apply(obj, [arg1, arg2]) //设置函数的运行环境(改变this的值)
  • bind(obj) //绑定函数的运行环境

Javascript中的正则表达式

1. RegExp类型的创建

var expression = /pattern/flags; 或者

var expression = new RegExp(“pattern”, “flags”);

用创建对象的方式来创建RegExp是需要对”pattern”中的\进行转义,例如:

/\[bc\]at/  => “\\[bc\\]at”

flags 可以是:

  • g :全局匹配
  • i :忽略大小写
  • m :多行模式

2. RegExp实例的属性

  • global: true or false, 表示标志位’g’是否被设置
  • ignoreCase: true or false
  • multiline: true or false
  • lastIndex: 下一次搜索开始的字符位置
  • source: pattern的字符串表示

3. RegExp实例的方法

  • exec(“target_string”)
    • ret.index: 匹配到的字符串的起始位置
    • ret.input: “target_string”
    • ret[0]: 匹配到的字符串
    • ret[1 – n]: 匹配组1-n匹配到的字符串
  • test(“target_string”)
    • true: 匹配到字符串
    • false: 没有匹配到字符串
  • exec和test只有在设置了’g’标志位的情况下才回去更新exp.lastIndex

4. RegExp 构造函数属性

  • input ($_): 最近一次匹配成功的源字符串
  • lastMatch($&): 最近一次的匹配项
  • lastParen($+): 最近一次匹配的捕获组
  • leftContext($`): input字符串中匹配项之前的字符串
  • rightContext($*): input字符串中匹配项之后的字符串
  • $1-9: 第1-9个匹配组

附录:

正则表达式元字符表

Metacharacter Description
^ Matches the starting position within the string. In line-based tools, it matches the starting position of any line.
. Matches any single character (many applications exclude newlines, and exactly which characters are considered newlines is flavor-, character-encoding-, and platform-specific, but it is safe to assume that the line feed character is included). Within POSIX bracket expressions, the dot character matches a literal dot. For example, a.c matches “abc”, etc., but [a.c] matches only “a”, “.”, or “c”.
[ ] A bracket expression. Matches a single character that is contained within the brackets. For example, [abc] matches “a”, “b”, or “c”. [a-z] specifies a range which matches any lowercase letter from “a” to “z”. These forms can be mixed: [abcx-z] matches “a”, “b”, “c”, “x”, “y”, or “z”, as does [a-cx-z].The - character is treated as a literal character if it is the last or the first (after the ^, if present) character within the brackets: [abc-], [-abc]. Note that backslash escapes are not allowed. The ] character can be included in a bracket expression if it is the first (after the ^) character: []abc].
[^ ] Matches a single character that is not contained within the brackets. For example, [^abc] matches any character other than “a”, “b”, or “c”. [^a-z] matches any single character that is not a lowercase letter from “a” to “z”. Likewise, literal characters and ranges can be mixed.
$ Matches the ending position of the string or the position just before a string-ending newline. In line-based tools, it matches the ending position of any line.
( ) Defines a marked subexpression. The string matched within the parentheses can be recalled later (see the next entry, \n). A marked subexpression is also called a block or capturing group. BRE mode requires \( \).
\n Matches what the nth marked subexpression matched, where n is a digit from 1 to 9. This construct is vaguely defined in the POSIX.2 standard. Some tools allow referencing more than nine capturing groups.
* Matches the preceding element zero or more times. For example, ab*c matches “ac”, “abc”, “abbbc”, etc. [xyz]* matches “”, “x”, “y”, “z”, “zx”, “zyx”, “xyzzy”, and so on. (ab)* matches “”, “ab”, “abab”, “ababab”, and so on.
{m,n} Matches the preceding element at least m and not more than n times. For example, a{3,5} matches only “aaa”, “aaaa”, and “aaaaa”. This is not found in a few older instances of regexes. BRE mode requires \{m,n\}.

 

Metacharacter Description
? Matches the preceding element zero or one time. For example, ab?c matches only “ac” or “abc”.
+ Matches the preceding element one or more times. For example, ab+c matches “abc”, “abbc”, “abbbc”, and so on, but not “ac”.
| The choice (also known as alternation or set union) operator matches either the expression before or the expression after the operator. For example, abc|def matches “abc” or “def”.

 

POSIX Non-standard Perl/Tcl Vim Java ASCII Description
[:ascii:][30] \p{ASCII} [\x00-\x7F] ASCII characters
[:alnum:] \p{Alnum} [A-Za-z0-9] Alphanumeric characters
[:word:][citation needed] \w \w \w [A-Za-z0-9_] Alphanumeric characters plus “_”
\W \W \W [^A-Za-z0-9_] Non-word characters
[:alpha:] \a \p{Alpha} [A-Za-z] Alphabetic characters
[:blank:] \s \p{Blank} [ [[\t]]] Space and tab
\b \< \> \b (?<=\W)(?=\w)|(?<=\w)(?=\W) Word boundaries
\B (?<=\W)(?=\W)|(?<=\w)(?=\w) Non-word boundaries
[:cntrl:] \p{Cntrl} [\x00-\x1F\x7F] Control characters
[:digit:] \d \d \p{Digit} or \d [0-9] Digits
\D \D \D [^0-9] Non-digits
[:graph:] \p{Graph} [\x21-\x7E] Visible characters
[:lower:] \l \p{Lower} [a-z] Lowercase letters
[:print:] \p \p{Print} [\x20-\x7E] Visible characters and the space character
[:punct:] \p{Punct} [][!"#$%&'()*+,./:;<=>?@\^_`{|}~-] Punctuation characters
[:space:] \s \_s \p{Space} or \s [ \t\r\n\v\f] Whitespace characters
\S \S \S [^ \t\r\n\v\f] Non-whitespace characters
[:upper:] \u \p{Upper} [A-Z] Uppercase letters
[:xdigit:] \x \p{XDigit} [A-Fa-f0-9] Hexadecimal digits

 

常用分组语法
分类 代码/语法 说明
捕获 (exp) 匹配exp,并捕获文本到自动命名的组里
(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?’name’exp)
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号
零宽断言 (?=exp) 匹配exp前面的位置
(?<=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(?<!exp) 匹配前面不是exp的位置
注释 (?#comment) 这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读

 

常用的反义代码
代码/语法 说明
\W 匹配任意不是字母,数字,下划线,汉字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

 

 

 

Javascript中的Date

1. Date类型的创建

  • var date = new Date() //获取当前时间
  • var date = new Date(ms) //根据Unix时间戳来创建Date对象
  • var date = new Date(Date.parse(“string”)) //string为日期时间组成的字符串,符合要求的字符串格式包括:
    • “m/d/y”
    • “January 12, 2004”
    • “Tue May 25 2004 00:00:00 GMT-0700”
    • YYYY-MM-DDTHH:mm:ss.sssZ”
  • var date = new Date(Date.UTC()) // Date.UTC的参数为年、月、日、小时、分钟、秒、毫秒

2. Date类型的操作

var date = new Date();

  • Date.now() 或者+new Date()获取当前的时间戳, “+”操作符可获取Date对象的时间戳
  • date.toDateString(); // “Thu May 17 2018”
  • date.toTimeString(); // “14:37:29 GMT+0800 (CST)”
  • date.toLocaleDateString(); // “2018/5/17”
  • date.toLocaleTimeString(); // “下午2:37:29”
  • date.toUTCString(); // “Thu, 17 May 2018 06:37:29 GMT”
  • date.toLocaleString(); // “2018/5/17 下午2:37:29”
  • date.getTime(); // 1526539049298
  • +date; // 1526539049298
  • date.setTime(1526539049300);
  • date.getFullYear(); // 2018
  • date.getUTCFullYear(); // 2018
  • date.getMonth(); // 0-11
  • date.getUTCMonth(); // 0-11
  • date.getDate(); //1-31
  • date.getUTCDate(); // 1-31
  • date.getDay(); // 0-6 0表示周日
  • date.getUTCDay(); // 0-6 0表示周日
  • date.getHours(); // 0-23
  • date.getUTCHours(); // 0-23
  • date.getMinutes(); // 0-59
  • date.getUTCMinutes(); // 0-59
  • date.getSeconds(); // 0-59
  • date.getUTCSeconds(); // 0-59
  • date.getMilliseconds(); // 0-999
  • date.getUTCMilliseconds(); // 0-999
  • date.getTimezoneOffset(); // -480

让javascript中的异步请求同步起来

在页面加载的时候,javascript通常会从服务器去获取一些数据,拿到数据后再渲染页面。如果用同步请求一个一个去拿这些数据,加载会很慢。但如果使用异步请求,后面的渲染操作会在数据返回之前就把页面给渲染了。

google了一下好像木有合适的解决办法, 于是我尝试用一个死循环挡在渲染页面之前,拿到数据后再跳出死循环。类似于这样的:

overview.showLoading();
instances.get_cluster(true);
users.get_users(true);
databases.get_databases(true);

for(;;) {
    if(ctrl.cluster && ctrl.databases && ctrl.users) {
        break;
    }
    setTimeout('', 500);
}

instances.show();
databases.show();
users.show();
overview.show();
overview.hideLoading();

get_cluster, get_databases, get_users会发起异步请求,请求成功后会把数据写到ctrl中去。看起来不错,可是执行起来浏览器会建议用户杀掉script,因为发现了死循环。木有办法,稍微变通一下,只能让死循环活半个小时,如果加载页面需要半个小时的话,你的网站可以歇菜了。于是改成下面的代码:

overview.showLoading();
instances.get_cluster(true);
users.get_users(true);
databases.get_databases(true);

for(var i =0; i < 3600; i++) {
    if(ctrl.cluster && ctrl.databases && ctrl.users) {
        break;
    }
    setTimeout('', 500);
}

instances.show();
databases.show();
users.show();
overview.show();
overview.hideLoading();

世界安静了,同步时不停转的loading也很快就消失了。

Javascript中的数组

  • 数组的定义:
    • var colors = new Array(20);
    • var colors = new Array(‘red’);  // [‘red’]
    • var colors = [‘red’, ‘green’];
  • 判断变量是不是数组:
    • colors instanceof Array;  //true
    • Array.isArray(colors); //true
  • 将数组转化为字符串:
    • colors.toString(); // ‘red,green’
    • colors.join(‘ ‘); //’red green’
    • colors = [ “red”, undefined, “green”, null, “yellow” ];
      • colors.toString(); //"red,,green,,yellow"
        
        colors.join(' '); //"red  green  yellow"
        
        colors.join(';'); //"red;;green;;yellow"
  • 栈方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.pop(); //[‘red’, ‘green’]
  • 队列方法
    • colors.push(‘yellow’); //[‘red’, ‘green’, ‘yellow’]
    • colors.shift(); //[‘green’, ‘yellow’]
    • colors.unshift(‘black’); //[‘black’, ‘red’, ‘green’]
  • 重新排序
    • colors.reverse(); //[‘green’, ‘red’]
    • colors.sort();
      • 字符串升序排列
        • var nums = [1, 5, 10]; //nums.sort();//[1, 10, 5]
      • colors.sort(function(a,b){return a – b;});升序排列
      • colors.sort(function(a,b){return b – a;});降序排列
  • 操作
    • var ret = colors.concat(‘black’); // ret = [‘red’, ‘green’, ‘black’]
    • var ret = colors.slice(0, 1); //[‘red’] 切片
    • colors.splice(pos, length, item, item…); 在pos处删除length项,然后插入item…
  • 位置
    • indexOf(‘red’); //0
    • lastIndexOf(‘red’); //0
  • 迭代
    • colors.every(function(item, index, array){}); 所有元素返回true则返回true
    • colors.filter(function(item, index, array){}); 返回为true的元素组成的数组
    • colors.forEach(function(item, index, array){}); 无返回值
    • colors.map(function(item, index, array){}); 返回函数调用结果组成的数组
    • colors.some(function(item, index, array){}); 如果有一项返回true则返回true
  • 归并方法
    • var sum = values.reduce(function(prev, cur, index, array){return prev + cur}, 0);
    • reduceRight(); 从后往前循环

Javascript中的基本数据类型

Undefined

  • 在var或者let中声明了变量但没有赋值时,这个变量的值就是undefined.
  • 使用typeof关键字检测未声明变量的类型为undefined.

Null

  • null表示一个空对象指针,所以用typeof检测null时,会返回object
  • undefine派生自null, null == undefined 为true, null === undefined为false

Boolean

  • true false 区分大小写
  • 空字符串、0和NaN、null、undefined转换为boolean的值为false

Number

  • Number表示整数和浮点数
  • 八进制数以0开头,十六进制数以0x开头
  • Number.MIN_VALUE 表示Javascript支持的正的最小数值,Number.MAX_VALUE表示Javascript支持的最大数值
  • 超出最大数值就会被转化为Infinity,如果为负值则会被转化为-Infinity
  • isFinite()函数可以判断一个数值是否在支持的范围之内
  • NaN表示本来该返回数值的操作数未返回数值的情况,如除以0就会返回NaN
  • NaN的数值运算会返回NaN
  • NaN == NaN 为false
  • isNaN()函数可以判断一个数值是不是NaN
  • Number()函数可以将其他类型的值转换为Number类型:
    • Number(true) = 1; Number(false) = 0;
    • Number(null) = 0;
    • Number(“”) = 0; Number(“0x1a”) = 26; Number(‘076’) = 76;
    • Number(‘100hello’) = NaN;
    • 如果是对象,则会调用对象的valueOf()方法,如果返回的是NaN则会先调用toString方法转化为字符串,然后根据字符串的转换规则来转换
  • parseInt()函数:
    • parseInt(‘100hello’) = 100;
    • parseInt(”) = NaN;
    • parseInt(‘0x1a’) = 26;
    • parseInt(‘076’) = 76; parseInt(‘076’, 8) = 62;
  • parseFloat()与parseInt()类似,但有如下区别:
    • parseFloat不能传入第二个参数(进制),不能解析十六进制字符串

String

  • 字符串一旦创建,其值不能改变,如:var lang = ‘Java’; lang += ‘Script’; 会重新创建一个字符串,填充上’JavaScript’, ‘Java’和’Script’都将被销毁
  • 除了null和undefined之外,其他的几个数据类型都有toString()方法,可以将其转换为字符串
  • 数值类型调用toString()方法可以传入进制作为参数,如:var a=20; a.toString(2);
  • String()方法可以将null转化为’null’,把undefined转化为’undefined’

React 概要

React 简介

React 是一个开源的javascript库,用来构建用户接口(UI)。下图是React的一些基本信息:

React 的特点

  1. 单向数据流
    • 数据自上而下
      • Props 不可变
      • States可变
      • 任何数据、函数都可以作为属性(props)传    递给子组件(Props, States, Handlers, Styles)
    • 事件冒泡
      • 子组件触发的事件会传递到父组件
  2. 虚拟DOM
    • Javascript内存中的DOM数据缓存
    • 组件发生变化时渲染虚拟DOM
    • React将虚拟DOM与DOM的差异转化为一系列的DOM操作
    • 将这些操作同步应用到真实的DOM中
  3. JSX
    • 可以使用HTML语法创建Javascript 对象
    • 代码更少
    • 会被转化为Javascript执行
      • Offline – react-tools
      • In-Browser – JSXTransformer
    • 不改变Javascript语义
  4. 其他特点
    • 元素嵌套: 每个组件只允许有一个顶层元素(div, table …)
    • 自定义属性: 除了HTML标签自带属性之外,React也支持自定义属性,自定义属性需要加上data- 前缀
    • JavaScript表达式: 可以通过{}在JSX中使用Javascript表达式
    • 三目运算符: JSX中不能使用if-else但可以使用三目运算符

React元素

const element = <h1>Hello, world</h1>;

  • React 元素 != DOM 元素
  • 将元素渲染到 DOM 中

    ReactDOM.render(element, document.getElementById(‘root’));
     

  • 更新元素 – 重新 Render
  • 更新元素只会更新变化的部分
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
  ReactDOM.render(
    element,
    document.getElementById('root')
  );
}
setInterval(tick, 1000);

React组件

组件可以将UI切分成一些的独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。

  • 如何定义一个组件
    • 函数
      function Welcome(props) {
        return <h1>Hello, {props.name}</h1>;
      }

       

    • class
      class Welcome extends React.Component {
        render() {
          return <h1>Hello, {this.props.name}</h1>;
        }
      }

       

  • 渲染组件
    • const element = <Welcome name=”Sara” />;
  • 组合组件
function App() {
  return (
    <div>
      <Welcome name="Sara" />
      <Welcome name="Cahal" />
      <Welcome name="Edite" />
    </div>
  );
}

状态与生命周期

因为react中props为只读,如果需要更新数据,可以使用react中的状态。在使用状态之前,需要把组件函数转变为类。

  • 创建一个名称扩展为 React.Component 的ES6 类
  • 创建一个叫做render()的空方法
  • 将函数体移动到 render() 方法中
  • 在 render() 方法中,使用 this.props 替换 props
  • 删除剩余的空函数声明

将组件函数转化为类之后就可以添加状态了:

  • 在 render() 方法中使用 this.state.date 替代 this.props.date
  • 添加一个类构造函数来初始化状态 this.state
  • 使用 this.setState() 来更新组件局部状
class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }
  componentDidMount() {
    this.timerID = setInterval(
      () => this.tick(),
      1000
    );
  }
  componentWillUnmount() {
    clearInterval(this.timerID);
  }
  tick() {
    this.setState({
      date: new Date()
    });
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}
ReactDOM.render(
  <Clock />,
  document.getElementById('root')
);

事件处理

  • React事件绑定属性的命名采用驼峰式写法,而不是小写。
  • 如果采用 JSX 的语法你需要传入一个函数作为事件处理函数,而不是一个字符串(DOM元素的写法)
  • React不能使用返回 false 的方式阻止默认行为

条件渲染

  • 使用 JavaScript 操作符 if 或条件运算符来创建表示当前状态的元素,然后让 React 根据它们来更新 UI
  • 使用变量来储存元素
    function Greeting(props) {
      const isLoggedIn = props.isLoggedIn;
      if (isLoggedIn) {
        return <UserGreeting />;
      }
      return <GuestGreeting />;
    }
    ReactDOM.render(
      // Try changing to isLoggedIn={true}:
      <Greeting isLoggedIn={false} />,
      document.getElementById('root')
    );

     

  • &&运算符
    function Mailbox(props) {
      const unreadMessages = props.unreadMessages;
      return (
        <div>
          <h1>Hello!</h1>
          {unreadMessages.length > 0 &&
            <h2>
              You have {unreadMessages.length} unread messages.
            </h2>
          }
        </div>
      );
    }

     

  • 三目运算符
    render() {
      const isLoggedIn = this.state.isLoggedIn;
      return (
        <div>
          The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
        </div>
      );
    }

     

列表渲染

  • React 可以直接渲染列表
  • Keys可以在DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。因此应当给数组中的每一个元素赋予一个确定的标识。
  • 元素的key只有在它和它的兄弟节点对比时才有意义
  • jsx中可以使用map
function ListItem(props) {
  return <li>{props.value}</li>;
}
function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

表单

  • HTML表单元素与React中的其他DOM元素有所不同,因为表单元素生来就保留一些内部状态
  • 在HTML当中,像<input>,<textarea>, 和 <select>这类表单元素会维持自身状态,并根据用户输入进行更新
  • 在React中,可变的状态通常保存在组件的状态属性中,并且只能用 setState(). 方法进行更新
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isGoing: true,
      numberOfGuests: 2
    };
    this.handleInputChange = this.handleInputChange.bind(this);
  }
  handleInputChange(event) {
    const target = event.target;
    const value = target.type === 'checkbox' ? target.checked : target.value;
    const name = target.name;
    this.setState({
      [name]: value
    });
  }
  render() {
    return (
      <form>
        <label>
          Is going:
          <input
            name="isGoing"
            type="checkbox"
            checked={this.state.isGoing}
            onChange={this.handleInputChange} />
        </label>
        <br />
        <label>
          Number of guests:
          <input
            name="numberOfGuests"
            type="number"
            value={this.state.numberOfGuests}
            onChange={this.handleInputChange} />
        </label>
      </form>
    );
  }
}