[关闭]
@EncyKe 2016-05-09T10:01:06.000000Z 字数 8953 阅读 3890

JavaScript【进阶篇】

前端 JavaScript



1. 数据类型

1.1 分类

JS属于弱类型语言,命名时无需指定数据类型。含六种数据类型:五种原始类型以及object:

1.2. 隐式转换

1.2.1. 用+/-可以隐式转换数据类型(number <-> string)

  1. // string → number
  2. str - '';
  3. // number → string
  4. num + '';

1.2.2. 用连等赋值将产生全局变量

  1. // 可实现a、b赋值为1,但b赋值后为全局变量;不推荐;
  2. var a = b = 1;
  3. // 推荐写法;
  4. var a = 1,
  5. b = 1;
  6. // 或者:
  7. var a = 1;
  8. var b = 1;

1.3. 类型检测

1.3.0. 用严格等于判断数据是否全等

严格等于:===,必须在数据类型全等的情况下才返回true。
注意:NaN ≠ NaN、[] ≠ []、{} ≠ {},即NaN === NaN[] === []{} === {}均将返回false。

1.3.1. typeof

用法:typeof obj,返回obj的类型字符串。
注意:typeof null; typeof Array;均将返回object。

1.3.2. instanceof

用法:obj instanceof Object,返回obj是否为Object的布尔值。

1.3.3. Object.prototype.toString.apply/call()

用法:Object.prototype.toString.apply(obj),返回obj的类型字符串。

或者(进阶用法):

用法:getType(obj)

  1. function getType(obj){
  2. return Object.prototype.toString.call(obj).slice(8,-1)
  3. }

2. 表达式与运算符

2.1. 表达式

2.2. 运算符

3. 语句

3.1. try语句

  1. try{
  2. // 执行;
  3. }catch{
  4. // 异常处理;
  5. }finally{
  6. // 不管异常与否均要执行;
  7. }

注意:catch和finally必有其一。

3.2. 严格模式

4. 对象

4.0. 对象简介

4.1. 对象创建

4.1.1. 对象字面量

  1. var obj = {
  2. x:1,
  3. y:2
  4. };

4.1.2. new构造器/原型链

  1. function fn(){}
  2. var obj = new fn();

有限原型链继承:obj → fn.prototype → Object.prototype → null

4.1.3. 由Object.create创建

  1. var obj = Object.create({x:1});

4.2. 属性定义

4.2.1. Object.defineProperty()方法

  1. Object.defineProperty(obj,'prop',{
  2. writable: true,
  3. enumerable: true,
  4. configurable: true,
  5. value: ''
  6. });
  7. // 三个标签默认为false;

4.2.2. Object.defineProperties()方法

  1. Object.defineProperties(obj,{
  2. prop1: {
  3. writable: true,
  4. enumerable: true,
  5. configurable: true,
  6. value: ''
  7. },
  8. prop2: {
  9. writable: true,
  10. value: ''
  11. }
  12. });

4.2.3. 属性判断技巧

  1. // 用于判断,表obj.prop !== undefined || obj.prop !== null
  2. obj.prop != undefined;
  3. // 用于判断,仅表obj.prop !== undefined
  4. obj.prop !== undefined;

4.3. 属性标签

4.3.1. 查看属性标签

  1. Object.getOwnPropertyDescriptor(obj,'prop');

属性标签详解

4.3.2. get/set方法

  1. get prop(){
  2. }
  3. set prop(val){
  4. }

4.4. 对象标签

4.4.1. prototype标签

4.4.2. class标签

  1. function getType(obj){
  2. return Object.prototype.toString.call(obj).slice(8,-1)
  3. }

4.4.3. extensible标签

4.5. 对象序列化

  1. // obj → JSON;
  2. JSON.stringify({x:1});
  3. // JSON → obj;
  4. JSON.parse('{"x":1}');

5. 数组

5.1. 数组创建

5.1.1. 字面量创建

  1. var arr = [];

5.1.2. new Array创建

  1. // 按数组长度创建(长度范畴:0 ~ 2^23-1);
  2. var arr = new Array(1024);
  3. // 按添加内容创建;
  4. var arr = new Array(1,2,3,4,5);

5.2. 数组增删

5.2.1. 尾部增一位

arr.push(val);
或者:
arr[arr.length] = val;

5.2.2. 头部增一位

arr.unshift(val);

5.2.3. 删特定一位(变其为undefined,长度不变)

  1. delete arr[index];
  2. index in arr; // => false

或者:

  1. arr[index] = undefined;
  2. index in arr; // => true;

5.2.4. 尾部删一位

arr.length -= 1;
或者:
arr.pop();

5.2.5. 头部删一位

arr.shift();

5.3. 数组方法

join()
reverse()
sort()
arr.sort(function(a,b){return a- b;})
concat()
slice()
splice()
forEach()
map()
filter()
every()
some()
reduce()
reduceRight()
indexOf()
lastIndexOf()
Array.isArray(arr);

6. 函数

6.1. 函数创建

6.1.0. 函数创建方式比较

  1. fnOne(); // 下面为函数声明语句,函数可在它之前被调用;
  2. funcion fnOne(){};
  3. fnTwo(); // 下面为函数表达式,函数不可在它之前被调用;
  4. var fnTwo = funcion(){}

函数创建方式比较

6.1.1. 函数声明

  1. function fn() {}

6.1.2. 函数表达式

A 函数变量表达式
  1. var fnAlias = function(){}
B 立即执行函数表达式 IEF (Immediately Executed Function)
  1. (function(){})()

或者:

  1. !function(){}()

或者:

  1. +function(){}()
C 一级函数表达式
  1. return function() {}
D 命名函数表达式 NFE (Named Function Expression)
  1. var fnAlias = function fn(){}

应用:递归调用

  1. var fnAlias = function fn(){ fn(); }

注意: NFE的兼容性及报错

  1. var fnAlias = function nfe() {};
  2. alert(fnAlias === nfe);
  3. // IE 6-8: false;
  4. // IE 9+, Ch, FF: error.

6.1.3. Function构造器

  1. var fn = new Function();

或者:

  1. var fn = Function();

或者:

  1. Function();

亦支持立即执行:

  1. Funtion()();

6.2. this关键字

6.2.0. this关键字与指向上下文

6.2.1. 全局下或直接调用的函数,this指向全局对象 (JS中是window,node.js中是global)

  1. function fn() {
  2. console(this);
  3. // this指代全局对象window或global;
  4. }

注意:严格模式下的函数内调用指向undefined。

6.2.2. 作为对象的方法,this指向对象

  1. var obj = {
  2. prop: '',
  3. fn: function () {
  4. console.log(this.prop);
  5. // this指向对象obj;
  6. }
  7. }

或者:

  1. var obj = { prop: '' };
  2. function f() {
  3. console.log(this.prop);
  4. }
  5. obj.fn = f;
  6. console.log(obj.fn());

6.2.3. 对象原型链上,this指向调用的对象

  1. var obj = {
  2. fn: function() {
  3. return this.prop;
  4. }
  5. }
  6. var p = Object.create(obj);
  7. p.prop = 31;
  8. console.log(p.fn()); // => 31;

6.2.4. 构造器中,this指向对象实例

  1. function Obj() {
  2. this.prop = '';
  3. this.fn = function () {
  4. console.log(this.prop);
  5. }
  6. // this指代对象示例Obj;
  7. }
  8. var obj = new Obj();

6.2.5. call()或者apply()方法改变上下文实现继承

  1. var obj = {
  2. prop: '',
  3. fn: function() {
  4. console.log(this.prop);
  5. }
  6. }
  7. obj.fn();
  8. var o= {
  9. prop: '',
  10. }
  11. obj.fn.call(o,prop);
  12. // call方法改变上下文,把fn方法中this指向的obj改为指向o;

或者(上述这一调用方法不太友好,亦可用构造函数):

  1. function Obj() {
  2. this.prop = '';
  3. this.fn = function() {
  4. console.log(this.prop);
  5. }
  6. }
  7. function OofObj() {
  8. Obj.call(this.prop);
  9. }
  10. var o = new OofObj();
  11. o.prop();

用法:

  1. function fn(c, d) {
  2. return this.a + this.b + c + d;
  3. }
  4. var obj = {
  5. a: 1,
  6. b: 2
  7. }
  8. fn.call(obj, 3, 4); // => 1 + 2 + 3 + 4
  9. fn.apply(obj, [3,4]); // => 1 + 2 + 3 + 4

6.2.6. bind()方法进行绑定

  1. function fn() {
  2. return this.prop;
  3. }
  4. var g = fn.bind({prop:'test'});
  5. console.log(g()); // =>test;
  6. var o = {prop: 31, fn: fn, g: g};
  7. console.log(o.fn(),o.g()); // =>31, 'test'

用法(currying):

  1. function fn(a, b, c) {
  2. return a + b + c;
  3. }
  4. var func1 = fn.bind(undefined, 100);
  5. func1(1,2); // => 100 + 1 + 2;
  6. var func2 = func1.bind(undefined, 200);
  7. func1(10); // => 100 + 200 + 10;

bind()是ES 5新特性,兼容性模拟如下:

  1. if (!Function.prototype.bind) {
  2. Function.prototype.bind = function(oThis) {
  3. if (typeof this !== 'function') {
  4. // closest thing possible to the ECMAScript 5
  5. // internal IsCallable function
  6. throw new TypeError('What is trying to be bound is not callable');
  7. }
  8. var aArgs = Array.prototype.slice.call(arguments, 1),
  9. fToBind = this,
  10. fNOP = function() {},
  11. fBound = function() {
  12. return fToBind.apply(this instanceof fNOP? this : oThis,
  13. aArgs.concat(Array.prototype.slice.call(arguments)));
  14. };
  15. fNOP.prototype = this.prototype;
  16. fBound.prototype = new fNOP();
  17. return fBound;
  18. };
  19. }

6.3. arguments关键字

  1. function fn(x,y,z) {
  2. arguments.length; // 取得实参个数;
  3. }
  4. fn(1,2);
  5. fn.length; // 取得形参个数;

6.4. 闭包

6.4.0. 闭包简介

优点:灵活、方便、可封装;
缺点:空间浪费、内存泄露、性能消耗;

6.4.1. 闭包应用

避免提升:

  1. for (var i = 1; i < 4; i++) {
  2. !function(i) {
  3. console.log(i); // 1, 2, 3
  4. }(i);
  5. }

封装变量:

  1. (function() {
  2. var _userId = 31;
  3. var _typeId = 'item';
  4. var export = {};
  5. function converter(userId) {
  6. return +userId;
  7. }
  8. export.getUserId = function() {
  9. return converter(_userId);
  10. }
  11. export.getTypeId = function() {
  12. return _typeId;
  13. }
  14. window.export = export;
  15. }());
  16. export.getUserId(); // 31
  17. export.getTypeId(); // item
  18. export._userId; // undefined
  19. export._typeId; // undefined
  20. export.converter; // undefined

6.5. 作用域

作用域链:

  1. function outer2() {
  2. var local2 = 1;
  3. function outer1() {
  4. var local1 = 1;
  5. // visit local1, local2 or global3
  6. }
  7. outer1();
  8. }
  9. var global3 = 1;
  10. outer2();

注意:

  1. function outer() {
  2. var i = 1;
  3. var func = new Function("console.log(typeof i);");
  4. func(); // =>undefined
  5. }
  6. outer();

7. 面向对象编程

7.1. 基于原型链的继承示例

JS类与原型继承

Student与Person继承关系图

7.1.1. 继承方法探究

  1. Student.prototype = Person.prototype; // 不推荐使用,同步机制;

或者:

  1. Student.prototype = new Person(); // 不推荐使用,传参不明;

或者:

  1. Student.prototype = Object.create(Person.prototype);
  2. Person.prototype.constructor = Person;

7.1.2. Object.create()兼容性模拟

  1. if (!Object.create) {
  2. Object.create = function(proto){
  3. function F(){};
  4. F.prototype = proto;
  5. return new F
  6. };
  7. }

7.1.3. 子类原型修改

7.2. 模拟重载实现示例

模拟重载实现示例

7.3. 调用子类示例

调用子类方法

7.4. 链式调用示例

链式调用

8. 正则表达式

8.1. 正则使用方法

/abc/gim.test('abc');
或者:
RegExp('abc','gim').test('abc');

8.2. 正则匹配一览表

符号 匹配字符串
. 任意字符
\d 数字0~9
\D \d,除数字0~9的其它字符
\w 数字0~9、字母a~z/A~Z、_
\W \w
\s Space、Tab、换页、换行
\S \s
\t Tab
\r Enter
\n 换行符
\f 换页符
\v 垂直制表符
[] 字符范围
[^] 字符范围以外
^ 行首
$ 行尾
\b 零宽单词边界
\B \b
(x) 分组
\数字 表用分组匹配到的字符串
(?:x) 仅分组不引用
* 贪婪算法,任意匹配,次数>=0
+ 贪婪算法,任意匹配,次数>0
x*? 非贪婪算法,同*
x+? 非贪婪算法,同+
x? 出现0或1次
`x y`
x{数字n} x重复次数为n
x{数字n,} x重复次数大于等于n
x{数字n,数字m} x重复次数满足:n <= x <= m

8.3. 正则匹配参数

g:global,全局匹配;
i:ignoreCase,不区分大小写;
m:multiline,跨行匹配;

8.4. 正则属性及方法

8.4.1. 正则表达式属性

8.4.2. 正则表达式方法


附:参考

慕课:JS深入浅出

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注