javascript注
1、浮点数:
- e表示法(科学计数法-10的指数次幂): let floatNum = 3.12e2; //等于312
- 浮点数的最高精度是17位小数。
- 浮点数计算精度远不如整数,0.15加0.15的和是0.3,但是0.1加0.2的和不是0.3而是0.30000000000000004。
- 因为浮点数的精度问题,所以比较两个浮点数是否相等只能判断差值是否小于某个阈值:Math.abs(a-b) < 0.00001;
2、数值:
- 数值范围:-Infinity(Number.NEGATIVE_INFINITY)到Infinity(Number.POSITIVE_INFINITY)
- NaN:非数值
- isNaN:判断元素是不是不是数字,isNaN('10'); //false,(可以被转换为数值10) isNaN('true'); //false,(可以被转换为数值1)
3、数值转换:
- Number()
- Boolean值,true和false分别被转换为1和0
- null值,返回0
- undefined值,返回NaN
- 数字值,返回数字
- 字符值,包含数字会直接返回数字(忽略前导的0),包含十六进制格式会返回对应的十进制整数,空的会返回0,否则就返回NaN。
- 对象,调用对象的valueOf()方法,然后依照前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,然后再次依照前面的规则转换返回的字符串值。
- parseInt()
- 字符值,包含数字会直接返回数字
- 0开头加数字的,ES3返回八进制对应的十进制数,ES5忽略前导的0,返回十进制数
- 0x开头加数字的,返回十六进制对应的十进制数
- parseFloat():始终都会忽略前导的0,只解析十进制数
4、字符串:
"I\'m ok!"; //如果字符串中含有引号可以用转义字符\ toUpperCase(); //把一个字符串变大写 toLowerCase(); //把一个字符串变小写 indexOf('ww'); //返回‘ww’在字符串里的索引位置 substring(2,5); //返回索引值在2-5之间的子串
5、数组:
var arr = [10, 20, 30, '30']; arr.indexOf('30'); //搜索指定元素的索引值,返回3 arr.slice(1,2); //截取索引值1-2之间的array元素,返回[20, 30] arr.push('A', 'B'); //向数组末尾添加若干元素 arr.pop(); //删除数组的最后一个元素 arr.unshift('B'); //向数组头部添加若干元素 arr.shift(); //删除数组的第一个元素 arr.sort(); //对数组进行排序,会直接修改当前数组的元素位置 arr.reverse(); //数组反转 arr.splice(2,3,'H','B'); //从索引2开始删除3个元素,再添加两个元素 arr.concat([1, 2]); //链接两个数组,返回新的数组 arr.join('-'); //数组遍历成字符串,并用指定的‘-’连接起来
6、对象
var jone = { name: 'Jone', birth: 1900, school: 'No.1 Middle School', height: 1.85,
age: function(){
var y = new Date().getFullYear() - this.birth; //this指向当前对象
return y;
} }; jone.height; //返回1.85 'name' in jone; //判断对象中是否有某个属性,返回true 'toString' in jone; //该属性是继承得到的,也返回true jone.hasOwnProperty('toString'); //判断属性是不是自身拥有的,返回false
jone.age();
function getAge(){ var y = new Date().getFullYear() - this.birth; return y; } var jone = { name: 'Jone', birth: 1900, school: 'No.1 Middle School', height: 1.85, age: getAge }; getAge.apply(jone, []); //jone调用getAge方法,参数为空 getAge.call(jone,); //jone调用getAge方法,参数为空
冻结对象jone:一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。
Object.freeze(jone);
7、Map(ES6,一组键值对)
var m = new Map([['Jone', 95], ['Bob', 80]]); m.get('Bob'); //返回80 m.set('Adam', 88); //添加新的key-value m.delete('Bob'); //删除key‘Bob’
8、Set(ES6,一组key的集合,没有重复的key)
var s1 = new Set(); //空set var s2 = new Set([1, 2, 3]); s2.add(4); //为set添加key‘4’ s2.delete(3); //为set删除key‘3’
9、iterable(ES6)
for ... in循环出来的是属性名,for...of完全修复了这些问题
var a = ['A', 'C', 'D'];
var s = new Set(['A', 'B']); var m = new Map([[1, 'x'], [2, 'y']]);
for(let x of a){ //遍历
console.log(x);
} for(let x of s){ //遍历 console.log(x); } for(let x of m){ //遍历 console.log(x[0] + '=' + x[1]); }
forEach是ES5.1标准引入的
//Set没有索引,因此前两个参数都是元素本身,参数可省略 var s = new Set(['1', '2']); s.forEach(function(element, sameElement, set){ console.log(element); }); //Map的参数依次为value、key、map本身 var m = new Map([['A', '1'], ['B', '2']]); m.forEach(function(value, key, map){ console.log(key + '=' + value); });
10、函数
函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。注意return语句一定不要换行。
function abs(a,b){ console.log(arguments.length); //返回函数参数的个数,返回2 }
...rest参数(ES6):用于返回除了前面参数外的所有参数,只能写在最后
function foo(a, b, ...rest){ console.log(rest); } foo(1,2,3,4,5); //返回[3, 4, 5]
11、变量作用域:全局变量和局部变量
- var声明的变量会向上提升
- ES6新的const和let变量都具有块级作用域
- 变量解构:let[x, y, z] = [1, 2, 3];
12、高阶函数
map():按照原始数组元素顺序一次处理元素,不会改变原始数组(参数:当前元素的值,当前元素的索引值,当前元素属于的数组对象)
function pow(x){ return x*x; } var arr = [1, 2, 3, 4]; var result = arr.map(pow); //result:[1, 4, 9, 16]
reduce():函数累加器,从左往右计算(参数:初始值,或者计算结束后的返回值,当前元素,当前元素的索引值,当前元素属于的数组对象)
var arr = [1, 3, 5, 7, 9]; arr.reduce(function(x,y){ return x*10+y; }); //13579
filter():根据特定条件过滤数组(参数:当前元素的值,当前元素的索引值,当前元素属于的数组对象)
var arr = [1, 2, 4, 6, 7]; var r = arr.filter(function(x){ return x%2 === 0; }); //[2, 4, 6]
//利用filter去除重复元素 var arr = ['app', 'saa', 'apple', 'app', 'des', 'apple']; var r = arr.filter(function(ele, index, self){ return self.indexOf(ele) === index; });
sort():按照指定规则为数组排序
//数字从小到大排序 var arr = [1, 50, 10, 2]; var r = arr.sort(function(x,y){ if(x<y){ return -1; }else if(x>y){ return 1; }else{ return 0; } });
//字母升序排列 var r = arr.sort(function(x1,y1){ x2 = x1.toUpperCase(); y2 = y1.toUpperCase(); if(x2<y2){ return -1; }else if(x2>y2){ return 1; }else{ return 0; } });
数组every():检测所有元素是否符合条件,如果都符合就返回true,否则返回false(参数:当前元素的值,当前元素的索引值,当前元素属于的数组对象)
//判断是否所有元素是不是小写 var arr = ['app', 'add', 'brand', 'bed']; var r = arr.every(function(x){ return x.toLowerCase() === x; });
数组find():查找符合条件的第一个元素(参数:当前元素的值,当前元素的索引值,当前元素属于的数组对象)
数组findIndex():查找符合条件的第一个元素的索引(参数:当前元素的值,当前元素的索引值,当前元素属于的数组对象)
generator(生成器,ES6):generator可以在执行过程中多次返回
try { r1 = yield ajax('http://url-1', data1); r2 = yield ajax('http://url-2', data2); r3 = yield ajax('http://url-3', data3); success(r3); } catch (err) { handle(err); }
13、Date对象
var d = new Date(); d; //Wed Jun 24 2015 19:49:22 GMT+0800 (CST) d.getFullYear(); //2015 d.getMonth(); //5 d.getDate(); //24 d.getDay(); //3 d.getHours(); //19 d.getMinutes(); //49 d.getSeconds(); //22 d.getMillideconds(); //675 d.getTime(); //1435146562875
14、RegExp正则表达式
\d匹配一个数字;\w匹配一个字母或数字;\s匹配一个空格;.匹配任意字符;*表示任意字符;+表示至少一个字符;?表示0或1个字符;{n}表示n个字符;{n,m}表示n-m个字符。
\d{3,8}; //匹配3-8个数字
要做更精确的匹配,可以用[]表示范围。^表示行的开头;$表示行的结尾。
^\d; //表示必须以数字开头 \d$; //表示必须以数字结尾 [0-9a-zA-Z\_]+; //表示至少由一个数字、字母或者下划线组成的字符串
js有两种正则表达式,一种是通过/正则表达式/写出来,第二种是通过new RegExp('正则表达式')创建出来。
var r1 = /^\d{3,8}\-\d{1,2}$/; var r2 new RegExp('^\d{3,8}\-\d{1,2}$');
正则表达式分组,()表示要提取的分组。
var r1 = /^(\d{3})-(\d{3,8})$/; r1.exec('010-123456'); //['010-123456', '010', '123456']
全局匹配g:当我们指定g
标志后,每次运行exec()
,正则表达式本身会更新lastIndex
属性,表示上次匹配到的最后索引(不能使用/^...$/
)
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,直到结束仍没有匹配到
15、面向对象编程
构造函数:
//每个对象都共享hello函数,减少内存 function Student(name){ this.name = name; } Student.prototype.hello = function(){ alert('Hello,' + this.name + '!'); } let l1 = new Student('Joe'); let l2 = new Student('Kitty'); l1.hello === l2.hello; //true
//不推荐,浪费内存 function Student(name){ this.name = name; this.hello = function(){ alert('Hello,' + this.name + '!'); } } let l1 = new Student('Joe'); let l2 = new Student('Kitty'); l1.hello === l2.hello; //false
class:
class student { constructor(name){ this.name = name; } } //class继承 class Cat extends Student { constructor(name){ super(name); //用super调用父类的构造方法 } say() { return 'Hello,' + this.name + '!'; } }
16、DOM
更新DOM:innerHTML和textContent
p.innerHTML = '<p>new</p>'; //html代码 P.textContent = 'new'; //纯文字
插入DOM:appendChild和insertBefore
<!-- HTML结构 -->
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
//appendChild
var list = document.getElementById('list');
var js = document.createElement('p');
list.appendChild(js);
//insertBefore
var java = document.getElementById('java ');
liat.insertBefore(js, java);
删除DOM:removeChild
liat.removeChild(java);
classList:
//contains判断是否包含样式 document.getElementById('a').classList.contains('active'); //add新增样式 document.getElementById('a').classList.add('active'); //remove移除样式 document.getElementById('a').classList.remove('active'); //toggle不管类名是否存在,true强制添加类,false强制移除类 document.getElementById('a').classList.toggle('active', true); document.getElementById('a').classList.toggle('active', false); //item返回索引值为0的类名 document.getElementById('a').classList.item(0); //length返回类的个数 document.getElementById('a').classList.length;
17、表单提交
出于安全考虑,提交表单时不传输明文口令,而是MD5
var pwd = document.getElementById('password'); var md5pwd = document.getElementById('md5-password'); md5pwd.value = toMD5(pwd.value); return true;
18、上传文件控件
let f = document.getElementById('text-file-upload'); let filename = f.value; //判断文件格式 if(!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))){ alert('请上传正确的文件格式!'); return false; }
上传图片并预览
<div id="image-preview" style="width: 400px; height: 400px; border: 1px solid gray; overflow: hidden;"> <img src="" alt="img" width="400" style="display: none;"> </div> <input id="image-upload" type="file" accept="image/jpeg,image/jpg,image/gif,image/png"> <script> let f = document.getElementById('image-upload'); let s = document.getElementById('image-preview').querySelector('img'); f.addEventListener('change',function(){ if(!(f.value)){ alert('没有选择文件'); return false; } //获取file信息 let file = f.files[0]; if(file.type !== 'image/jpeg' && file.type !== 'image/jpg' &&file.type !== 'image/gif' &&file.type !== 'image/png'){ alert('不是有效的图片文件'); return false; } //限制图片格式 if(file.size/1024>2048){ alert('上传图片大小不要超过2M'); return false; } //限制图片大小 //读取文件 let reader = new FileReader(); reader.onload = function(e){ s.src = e.target.result; s.style.display = 'block'; }; //以DataURL的形式读取文件 reader.readAsDataURL(file); }); </script>
19、JSON
JSON.stringify(obj); //对象转换为json串
20、
21、
offsetWidth | 水平方向 width + 左右padding + 左右border-width |
offsetHeight | 垂直方向 height + 上下padding + 上下border-width |
clientWidth | 水平方向 width + 左右padding |
clientHeight | 垂直方向 height + 上下padding |
offsetTop | 获取当前元素到 定位父节点 的top方向的距离 |
offsetLeft | 获取当前元素到 定位父节点 的left方向的距离 |
scrollWidth | 元素内容真实的宽度,内容不超出盒子高度时为盒子的clientWidth |
scrollHeight | 元素内容真实的高度,内容不超出盒子高度时为盒子的clientHeight |
innerWidth | 浏览器窗口可视区宽度(不包括浏览器控制台、菜单栏、工具栏) |
innerHeight | 浏览器窗口可视区高度(不包括浏览器控制台、菜单栏、工具栏) |