1. 变量定义
1. var
- 变量提升
- 重新定义会覆盖
- 变量提升只会提升变量名的声明,而不会提升变量的赋值初始化
//相当于声明提升
//var a;
console.log(a);
var a = 1;
2. let
-
无变量提升
-
不可重新定义
-
块作用域
作用于{ }内部
for(let i = 0 ;i < aLi.length ; i++){
console.log(i);
//输出0 1 2
}
console.log(i);
//报错
- 闭包
- 外部函数调用之后其变量对象本应该被销毁,但闭包的存在使我们仍然可以访问外部函数的变量对象,这就是闭包的重要概念。
for(let i = 0 ;i <= aLi.length ;i++){
//一级作用域
aLi[i].onclick = function(){
//二级作用域
console.log(i);
}
}
3. const
- const 用于声明一个或多个常量,声明时必须进行初始化,不可重新赋值
- 块级作用域
- 不能和它所在作用域内的其他变量或函数拥有相同的名称
- 使用 const 定义的对象或者数组,其实是可变的。下面的代码并不会报错
const obj = {
name:'xiaoming';
age:'2';
}
obj.age = '3';
console.log(obj);//修改成功
obj = {
name:'xiaoming';
age:'4';
}
console.log(obj);//报错
- const 关键字在不同作用域,或不同块级作用域中是可以重新声明赋值的
2. 暂时性死区
- 在代码块内,使用let声明变量之前,该变量都是不可用的
var x =5;
var fun = function(){
console.log(x);
//报错
let x;
}
3. 冻结
- 冻结后不可修改 但修改后不报错 显示原来信息
Object.freeze(obj);
4. 变量解构赋值
解构 :从数组和对象中提取值,对变量进行赋值
1. 数组的解构
- 按照顺序依次赋值
var [a,b,c] = [1,2,3];
2. 对象的解构
- 按照key赋值
let {name,age} = {name:'xm',age:4};
console.log(name,age);
//取别名
let {name:x,age} = {name:'xm',age:4};
console.log(x,age);
3. 字符串的解构
- 把字符串中每一个字符提取出来分别进行赋值
const [a,b,c,d,e] = 'hello';
console.log(a); //h
console.log(b); //e
console.log(c); //l
console.log(d); //l
console.log(e); //o
let { length : len} = 'yahooa';
console.log(len); //5
4. 解构用途
- 深拷贝
let x = 2;
let y = 3;
[y,x]=[x,y];
console.log(x);//3
console.log(y);//2
5. 扩展运算符(...)
1. 数组
- 数组合并
- 数组复制(深拷贝)
JSON.stringify( )JSON.parsedeepClone()- 解构运算符
concat( )silce( )只是对数组的第一层进行深拷贝
let array = [1,2,3]
var a1 = [...array]; // 复制一个数组 可以实现数组的深拷贝
console.log(a1); //[1,2,3]
let a2 = [...array,'a','b'] //作为数组的一部分
console.log(a2);//[1,2,3,'a','b']
let a3 = array;
console.log(a3) //[1,2,3]
array[0] = 4;
console.log(a3) //[4,2,3]
console.log(a1); //[1,2,3]
let a4 = [4,5,6]
let a5 = [...array,...a4] // 数组的合并
console.log(a5)//123456
console.log(array)//123
console.log(a4)//456
let a6 = [1,2,3]
let a7 = [4,5,6]
console.log(a6.concat(a7))//123456
console.log(a6)//123
console.log(a7)//456
2. 对象
- 合并对象
- 不同的属性会合并,相同的属性 后面的会把钱前面的覆盖
- 对象深拷贝
deepClone( )- 扩展运算符
let p1 = {
name: 'xm',
age: '4'
}
let p2 = {...p1}
p1.age = 2;//p2不会改变
let p1 = {
name: 'xm',
age: '4'
}
let p2 = {
weight: '8kg',
age: '2'
}
let p3 ={...p2,...p1} // 对象的合并
.
3. 类数组转数组
- 扩展运算符
Array.from( )
let aLi = document.querySelectorAll('li'); //NodeList
console.log(aLi);
let b = [];
for(let c = 0; c<aLi.length; c++){
b[c] = aLi[c]
}
console.log(b)
let aList = [...aLi]; // 可以将类数组转换成数组
console.log(aList);
aList.push('wxc');
console.log(aList);
let b1 = document.getElementsByTagName('li'); //HTMLCollection
console.log(b1)
// rest 剩余的
function fun(x,...rest){
console.log(x);
console.log(rest);
}
fun(1,2,3,4)
console.log('----------')
function fun1(){
// arguments.callee 当前方法
console.log(11111)
// arguments.callee() 递归调用
}
fun1(1,2,3,4)
6. rest
function fun(x...rest){
console.log(x);//1
console.log(rest);//234
}
fun(1,2,3,4);
7. 函数的扩展
1. fun.length
获取没有设置默认值的形参个数
2. fun.name
获取方法名
3. 箭头函数 =>
- this指向父作用域this
- 不可以使用
arguments获取参数,可以使用rest获取参数 - 函数中只有一行代码 { } 可以省略
// 箭头函数中不可以使用arguments获取参数,可以使用rest获取参数
var fun3 = (...rest) => {
console.log(rest);
rest[0];
}
fun3(1,2,3)
4. arguments
- 一个数组
- 方法不设形参时 用arguments接受传的参数
- arguments.callee 当前正在执行的函数(本身),递归
function fun([x,y,z=4]){ // 设置默认值
//只有是undefined的时候才会使用默认值
console.log(x,y,z)
}
8. 模板字符串
- 使用 `` 包裹字符串
- 拼接 `` 括起来后 用${ }拼接
`Hello ${name}, how are you ${time}?`
9. 字符串方法
1. Number.includs( )
检索字符串 返回true/false
2. Number.startsWith( )
返回布尔值 表示参数字符串是否在原字符串的头部
3. Number.endsWith( )
返回布尔值 表示参数字符串是否在原字符串的尾部
4. padStart()用于头部补全,padEnd( )用于尾部补全
- 如果省略第二个参数,默认使用空格补全长度
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(0, 'ab') // 'x'
5. repeat(n)
- 返回一个新字符串,表示将原字符串重复n次
'x'.repeat(3) // "xxx"
10. 数值的扩展
1. Number.isFinite( )
- 用来检查一个数值是否为有限finite
Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
- 如果参数类型不是数值,Number.isFinite返回false。
2. Number.isNaN( )
- 用来检查一个值是否为NaN。
Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true
- 如果参数类型不是NaN,Number.isNaN返回false。
3. Number.isInteger( )
- 用来判断一个数值是否为整数
Number.isInteger(25) // true
Number.isInteger(25.1) // false
Number.isInteger('15') // false
5. Number.parseInt( )和Number.parseFloat( )
- 转为整数/浮点数
Number.parseInt('12.34') // 12
Number.parseInt(5.1) // 5
Number.parseFloat('123.45#') // 123.45
11. Math对象扩展
1. Math.trunc( )
- Math.trunc方法用于去除一个数的小数部分,返回整数部分。
Math.trunc(4.1) // 4
Math.trunc(4.9) // 4
Math.trunc(-4.1) // -4
Math.trunc(-4.9) // -4
Math.trunc(-0.1234) // -0
2. Math.sign( )
-
判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
- 正数 返回 +1
- 负数 返回 -1
- 0 返回 0
- -0 返回-0
- 其他 返回 NaN
12. 数组扩展
1. Array.from( )
- 将对象转为真正的数组(类数组的对象/对象)
2. Array.of( )
- 将值转换为数组
Array.of(3, 11, 8) // [3,11,8]
Array.of(3) // [3]
3. array.copyWithin( )
- 在当前数组内部,将指定位置的成员复制到其他位置(覆盖原有成员),然后返回当前数组,会修改当前数组
Array.prototype.copyWithin(target, start = 0, end = this.length)
- target(必需):从该位置开始替换数据。如果为负值,表示倒数。
- start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。
- end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。
// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}
// 将2号位到数组结束,复制到0号位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// 对于没有部署 TypedArray 的 copyWithin 方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]
4. array.find( )
- 用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
//找出数组中第一个小于 0 的成员。
[1, 4, -5, 10].find((n) => n < 0)
// -5
[1, 5, 10, 15].find(function(value, index, arr) {
return value > 9;
}) // 10
5. array.findIndex( )
- 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
6. array.fill( )
- 使用给定值,填充一个数组。
['a', 'b', 'c'].fill(7)
// [7, 7, 7]
new Array(3).fill(7)
// [7, 7, 7]
- fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
['a', 'b', 'c'].fill(7, 1, 2)
// ['a', 7, 'c']
7. for...of
- 循环输出数组每一项值
- keys()是对键名的遍历
- values()是对键值的遍历
- entries()是对键值对的遍历
for(ietm of p){
console.log(item);
}
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
8. array.includes( )
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
9. array.forEach( )
- 遍历数组
p.forEach(function(value,key,arry){
console.log(value);
})
10. array.filter( )
- 返回所有符合条件的内容的数组
[1, 5, 10, 15].filter(function(value, index, arr) {
return value > 9;
}) // 10 15
13. 对象的扩展
1. 属性的简洁表示法
let name = 'xc';
let age = '18';
let obj = {
name,//属性简写
age,
eating(){//方法简写
console.log('meat');
}
}
2. 属性名表达式
- JavaScript 定义对象的属性,有两种方法
// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
3. Object.is( )判断严格相等
+0 === -0 //true
Object.is('-0',+0) //false
NaN === NaN //false
Object.is('NaN',NaN) //true
4. assign( )
- 方法用于对象的合并
- 如果只有一个参数,
Object.assign会直接返回该参数。 - 如果该参数不是对象,则会先转成对象,然后返回。
const target = { a: 1, b: 1 };
const source1 = { b: 2, c: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
//target {a:1, b:2, c:3}
//如果只有一个参数,Object.assign会直接返回该参数。
const obj = {a: 1};
Object.assign(obj) === obj // true
//如果该参数不是对象,则会先转成对象,然后返回。
typeof Object.assign(2) // "object"
5. Object.keys Object.values Object.entries
- 作为遍历一个对象的补充手段,供
for...of循环使用 - 返回数组
let {keys, values, entries} = Object;//对象解构赋值
let obj = { a: 1, b: 2, c: 3 };
for (let key of keys(obj)) {
console.log(key); // 'a', 'b', 'c'
}
for (let value of values(obj)) {
console.log(value); // 1, 2, 3
}
for (let [key, value] of entries(obj)) {
console.log([key, value]); // ['a', 1], ['b', 2], ['c', 3]
}
6. 'name' in object
- 对象是否具有属性
- 返回布尔值
14. AJAX
- 异步 JavaScript 和 XML。
- AJAX 是一种用于创建快速动态网页的技术。
1. 创建XMLHttpRequest对象
- 为了应对所有的现代浏览器,请检查浏览器是否支持 XMLHttpRequest 对象。如果支持,则创建 XMLHttpRequest 对象。如果不支持,则创建 ActiveXObject
var xmlhttp;
if (window.XMLHttpRequest){//code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{//code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
2. 请求
| 方法 | 描述 |
|---|---|
| open(method,url,async) | 规定请求的类型、URL 以及是否异步处理请求。 method:请求的类型GET 或 POST url:文件在服务器上的位置 async:true(异步)或 false(同步) |
| send(string) | 将请求发送到服务器。 string:仅用于 POST 请求 |
xmlhttp.open("GET","test1.txt",true);
xmlhttp.send();
3. 响应
- XMLHttpRequest 对象的三个重要的属性
| 属性 | 描述 |
|---|---|
| onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
| readyState | 存有 XMLHttpRequest 的状态。 0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 4: 请求已完成,且响应已就绪 |
| status | 200: "OK" 400:请求出现语法错误 404: 未找到页面 500:服务器错误 505:HTTP版本不受支持”,当服务器不支持请求中所使用的HTTP协议版本 304:客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。 |
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
15. jquery ajax
1. jQuery.ajax( url [, settings ] )
-
执行一个异步的HTTP(Ajax)的请求。
-
url
类型: String 一个用来包含发送请求的URL字符串。
-
settings
类型: PlainObject 一个以"{键:值}"组成的AJAX 请求设置。所有选项都是可选的。可以使用$.ajaxSetup()设置任何默认参数。看jQuery.ajax( settings )下所有设置的完整列表。
$.ajax({
accepts: {
mycustomtype: 'application/x-some-custom-type'
},
// Instructions for how to deserialize a `mycustomtype`
converters: {
'text mycustomtype': function(result) {
// Do Stuff
return newresult;
}
},
// Expect a `mycustomtype` back from server
dataType: 'mycustomtype'
});
2. jQuery.get( url [, data ] [, success ] [, dataType ] )
- 使用一个HTTP GET请求从服务器加载数据。
-
url
类型:String 一个包含发送请求的URL字符串.
-
data
类型:PlainObject or String 一个普通对象或字符串,通过请求发送给服务器。
-
success
类型:Function( PlainObject data, String textStatus, jqXHR jqXHR ) 当请求成功后执行的回调函数。 如果提供dataType选项,那么这个success选项是必须的, 但你可以使用null或jQuery.noop作为占位符。
-
dataType
类型:String 从服务器返回的预期的数据类型。默认:智能猜测(xml, json, script, text,html)。
-
$.ajax({
url: url,
data: data,
success: success,
dataType:dataType,
method:method
});
$.get('ajax/test.html', function(data) {
$('.result').html(data);
alert('Load was performed.');
});
16. 基本数据类型
1. symbol
- 独一无二的值不会与其他属性重复
- 对象下属性是
symbol不会在for...in循环出来
let obj = {
name : 'xiaoming',
age : '18'
}
let height = Symbol ( );
obj [height] = "180cm"//for in中无
2. set
- 类似于数组
- 数组去重
let arr = [4, 1, 3, 3, 2, '2'];
let uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [4, 1, 3, 2, "2"]
set.add(value)添加某个值set.delete(value)删除某个值,返回布尔值,表示删除是否成功set.has(value)返回一个布尔值,表示该值是否为Set的成员set.clear()清除所有成员,没有返回值set.size长度
let s = new Set();
s.add(1).add(2).add(2);
// 注意2被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
s.delete(2);
s.has(2) // false
3. map
- 类对象
map.set('key', 'value')map.get('key')map.delete('key')删除某个值,返回布尔值,表示删除是否成功map.has('key')返回一个布尔值,表示该值是否为Map的成员map.clear()清除所有成员,没有返回值set.size长度- 类对象转化成对象
let a = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let b = {};
a.forEach(function (value, key) {
console.log(key);
b[key] = value;
})
console.log(b);
17. promise(异步编程)
- Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。
- resolve 成功回调
- reject 失败回调
1. Promise.prototype.then()
- 为 Promise 实例添加状态改变时的回调函数
2. Promise.prototype.catch()
- 用于指定发生错误时的回调函数
const promise = new Promise(function(resolve, reject) {
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
//方法一
const promise = new Promise(function(resolve, reject) {
setTimeout(function(){
reject();
},2000)
}).then(function(){//成功
//code
}).catch(function(){//失败
//code
});
//方法二
const promise = new Promise(function(resolve, reject) {
setTimeout(function(){
reject();
},2000)
}).then(function(){//成功
//code
},function(){//失败
//code
});
3. Promise.prototype.finally()
- finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
4. Promise.all
- 用于将多个 Promise 实例,包装成一个新的 Promise 实例。
- 接受一个数组作为参数,p1、p2、p3都是 Promise实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。
// 生成一个Promise对象的数组
const promises = [2, 3, 5, 7, 11, 13].map(function (id) {
return getJSON('/post/' + id + ".json");
});
Promise.all(promises).then(function (posts) {
// ...
}).catch(function(reason){
// ...
});
5. Promise.race
- 同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
- 只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
const p = Promise.race([p1, p2, p3]);
18. 类
1. ES5继承
- ES5继承
function Person(_name, _age){
this.name = _name,
this.age = _age
}
Person.prototype.eat = function(){
console.log(111)
}
function Student(_name,_age){
Person.call(this, _name, _age);//继承父类属性
}
Student.prototype = new Person();//指向父类原型
Student.prototype.constructor = Student;//指向自己构造方法
let s1 = new Student('jj',18);
console.log(s1.eat);
s1.eat();//调用父类方法
2. ES6继承
- ES6 可以通过
extends关键字实现继承 - 父类的静态方法,也会被子类继承。
- 静态方法只能通过类名调用
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static hello() {
console.log('hello world');
}
toString() {
console.log('red')
}
}
class ColorPoint extends Point {
constructor(x, y, color) {
this.color = color; // ReferenceError
super(x, y);// 调用父类的constructor(x, y)
this.color = color; // 正确
}
toString() {
return this.color + ' ' + super.toString(); // 调用父类的toString()
}
}
ColorPoint.hello();//hell world
19. Generator(异步编程)
- Generator函数是ES6提供的一种异步编程解决方案
function* fun() {
console.log("start");
yield request();//yield语句执行完成后停止
console.log("end");
}
function request() {
setTimeout(() => {
console.log("success");
}, 2000)
}
let _fun = fun();//指针对象
console.log(_fun.next());//{value: yield返回值, done: false}
_fun.next();
console.log(_fun.next());//next可传值,是上一个表达式返回值
20. async(异步编程)
async function fun() {
console.log("start...");
let data = await request();
console.log(data);//14
let data1 = await request1(data);//拿到上次的返回结果
console.log(data1);//16
console.log("end...");
}
function request(){
return new Promise(function(resolve,reject){
setTimeout(() => {
let obj = {
name: 'jj',
age: 18
}
console.log("success");
resolve(obj);
}, 2000)
})
}
function request1(_tmp){
console.log(_tmp);//32
return new Promise(function (resolve, reject) {
setTimeout(() => {
let obj = {
name: 'ccc',
age: 1
}
console.log("success1");
resolve(obj);
}, 2000)
})
}
fun();
//打印结果
1.html:12 start...
1.html:26 success
1.html:14 {name: "jj", age: 18}
1.html:32 {name: "jj", age: 18}age: 18name: "jj"__proto__: Object
1.html:39 success1
1.html:16 {name: "ccc", age: 1}
1.html:17 end...
21. proxy
- Proxy 用于修改某些操作的默认行为(拦截)
let obj = {
name: 'ccc',
age: 1
}
//拦截对象
let pro = new Proxy(obj,{
set(target,key,property){
console.log(target, key, property);//{name: "ccc", age: 1} "name" "11111"
target[key] = property;//实际应用中property改写成需要的数值
},
get(target, key, property){
console.log(target, key, property);//{name: "11111", age: 1}"name" Proxy-{name: "11111", age: 1}
return target[key];
}
})
pro.name = '11111';
console.log(obj);//{name: "11111", age: 1}
console.log(pro.name);//11111