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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# 很久没用js了,有些生疏,正好看到廖老师的js教程,回顾下。网址如下: http://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000 # 一些简单介绍如下: // ECMAScript是一种语言标准,而JavaScript是网景公司对ECMAScript标准的一种实现 // 最新版ECMAScript 6标准(简称ES6)ECMA(European Computer Manufacturers Association) // chrome console可以简单调试js代码 js是严格区分大小写 // NaN:Not a Number null:空 undefined:未定义 Infinity:无限大 number:所有的数字 // NaN === NaN;(false) isNaN(NaN);(true) typeof variable === 'number' typeof variable === 'undefined' ... // js设计缺陷(声明变量可以不用var,这样变量就变成了全局变量),如果多个页面不用var,就会导致变量相互冲突 // ECMA在后续规范中推出了strict模式 如果没有用var声明变量 就会导致运行错误 'use strict'; # 数组(通常使用[],更简单高效) [1, 3.14, 'hello', true, null, ...]; new Array(); # 对象 // js对象不管加不加'',其实它的字段名都是字符串 var obj = { name : '张三', 'age' : 13, tags : ['js', 'php'], // 最后一个值后面不要加, 如果字段名不符合变量标准(字符数字下划线,字母开头) 必须使用'' 'middle-school' : 'No.1 middle school' }; obj.name; obj['name']; obj['middle-school']; //不符合变量标准的字段名只能用[]语法 obj.test; //undefined obj.test = 1; //动态添加 delete obj.test; //删除 'age' in obj; //true 'toString' in obj; //true in判断,会有继承的情况,所有对象都会在原型链上指向object object拥有toString属性 obj.hasOwnProperty('toString'); //false 如果要判断当前对象中是否包含某个属性,用hasOwnProperty # 最新的ES6(ECMAScript6的缩写)引入 'use strict'; // `...` 多行字符串 `abcdefg hijklmno pqrstuvw xyz`; // 变量替换${variable},类似php的{$variable} var name = '小明'; var age = 20; var message = `我叫,${name},今年${age}岁了。`; // 引入Map var m = new Map([ ['Michael', 95], ['Bob', 75] ]); m.get('Michael'); //95 m.set('Adam', 58); //添加 m.set('Bob', 59); //设置 m.has('Adam'); //true m.delete('Adam'); //删除 m.get('Adam'); //undefined // 引入Set var s = new Set([1,2,3,3,'3']); //{1,2,3,"3"} 重复的会被过滤 s.add(4); //添加,重复值添加不进去 s.delete(1); //删除 # iterable类型 Array、Map和Set都属于iterable类型 // for...in由于历史遗留问题,它遍历的实际上是对象的属性(字段) var a = ['A','B','C']; a.name = 'hello'; for(var x in a) { alert(x); //依次输出 0 1 2 name } alert(a.length); //长度依然是3 for (var x of a) { alert(x); //依次输出 A B C } // forEach是ES5.1引入 效果跟for...of类似 a.forEach(function (element, index, array) { // element: 指向当前元素的值 // index: 指向当前索引 // array: 指向Array对象本身 alert(element); //依次输出 A B C alert(index); //依次输出 0 1 2 alert(array.name); //依次输出 hello hello hello alert(array[index]); //依次输出 A B C }); // Set和Array类似,但Set没有索引,所以前2个参数都是指向当前元素的值 s.forEach(function(element, sameElement, set){}); // Map的回调函数的参数依次为value、key、map本身 m.forEach(function(value, key, map){}); # 函数 // js允许传入任意个数的参数 function abs(num) { if (typeof num !== 'number') { throw 'Not a number'; } if (num >= 0) { return num; } return -num; } abs(-9, 'haha', 'hehe', null); //9 后面的参数被忽略 //不进行参数检查:NaN 参数undefined,所以返回NaN //进行参数检查:会抛一个 Not a number 的异常 abs(); // 利用arguments处理 function abs() { if (arguments.length === 0) { return 0; } var num = arguments[0]; return num >= 0 ? num : -num; } abs(-9, 'haha', 'hehe', null); //9 abs(); //0 // 利用arguments做可选参数,参数默认值 // 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null function foo(a, b, c){ if (arguments.length === 2) { c = b; b = null; } } // ES6引入rest参数 rest只能在最后面,前面用...标识 如果参数没填满,rest是一个空数组 function sum(a, b, ...rest) { var rs = a + b; for(var i = 0; i < rest.length; i++) { rs += rest[i]; } return rs; } alert(sum(1,2,3,4,5)); //15 // 函数嵌套,内部函数可以访问外部函数定义的变量,反之则不行 function foo() { var x = 1; function bar() { var y = x + 1; //bar可以访问foo的变量x } var z = y + 1; //foo不可以访问bar的变量y } // 变量重名,js的函数查找变量时是从自身函数开始由"内"向"外"查找 function foo() { var x = 1; function bar() { var x = 'A'; alert(x); //A } alert(x); //1 bar(); } // 变量提升(以下函数不会报错,而是输出hello undefined) // 因为y变量被js提升了 相当于在alert之前 var y; 然后在alert之后赋值 function foo() { var x = 'hello ' + y; alert(x); var y = 'boy'; } # 作用域 // 全局作用域(不在任何函数内的变量具有全局作用域,实际上被绑定到window的一个属性) var course = "Learn JavaScript"; alert(course); //Learn JavaScript alert(window.course); //Learn JavaScript // 其实,我们平时使用的alert也是window的一个属性 window.alert("test"); //test var oldAlert = window.alert; window.alert = function(data) { //这样就能修改原生的alert方法 // do something }; // 名字空间(可以避免多文件变量冲突) // 全局变量会绑定到window上,不同的js文件,可能会使用相同的变量名,导致冲突 var MyApp = {}; //充当当前文件的window MyApp.name = 'myapp'; MyApp.foo = function() { return 'foo'; }; // 局部作用域 // ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量 function foo() { for (var i = 0; i < 10; i++) { } alert(i); //10 for (let j = 0; j < 10; j++) { } alert(j); //j is not defined } // ES6引入const来定义常量,const和let都具有块级作用域 const PI = 3.14; |