声明变量
var:重复声明,变量提升,函数级,不限制修改。
let :不能重复声明,块级作用域,不能变量提升,暂时性死区。
const: 声明一个只读的常量。一旦声明,常量的值就不能改变。
数据类型检测
typeof 适合用来检测基本数据类型:number string boolean function object undefined
instanceof 实例的具体类型(返回的是true和false)
检测子级类型+父级类型
constructor 返回实例的构造函数
精确类型判断(只检测包括子级,不包括父级)
解构赋值
基本用法
let [foo, [`[bar], baz]] = [1, [[2], 3]];`
foo // 1
bar // 2
baz // 3
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
let [x, , y] = [1, 2, 3];
x // 1
y // 3
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
foo // "aaa"
bar // "bbb"
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
baz // "aaa"
let obj = { first: 'hello', last: 'world' };
let { first: f, last: l } = obj;
f // 'hello'
l // 'world'
默认值
let [foo = true] = [];
foo // true
let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
var {x = 3} = {};
x // 3
var {x, y = 5} = {x: 1};
x // 1
y // 5
var {x: y = 3} = {};
y // 3
var {x: y = 3} = {x: 5};
y // 5
var { message: msg = 'Something went wrong' } = {};
msg // "Something went wrong"
1.两边的结构必须一样
2.右边必须得是个东西
3.赋值和解构同时完成
箭头函数
ES6的箭头函数 :()=>{}
普通函数 :function(){}
var f = v => v;
// 等同于
var f = function (v) {
return v;
};
实用注意
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,默认情况下this指向window。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
箭头函数的简写
1.如果有且仅有一个参数,()也可以不写
2.如果有且仅有一个语句并且是return,{}也可以不写
Promise
含义
Promise 是异步编程的一种解决方案,用同步一样的方式,书写异步的代码。
Promise.all([
$.ajax({url: 'data/1.txt', dataType: 'json'}),
$.ajax({url: 'data/2.txt', dataType: 'json'}),
$.ajax({url: 'data/3.txt', dataType: 'json'}),
]).then(([data1, data2, data3])=>{
console.log(data1, data2, data3);
}, res=>{
alert('失败');
});
异步操作:同时进行多个操作,用户体验;代码混乱
同步操作:一次只能进行一个操作,用户体验不好;清晰
async/await(也是一种异步的编程方式)
async function show(){
xxx;
xxx;let data=await $.ajax();
xxx;
}
show();
数组
map(映射)
let arr=[12, 5, 8, 99, 27];
let arr2=arr.map(item=>item*2);
alert(arr2);
reduce(汇总)
let arr=[12, 5, 8, 99, 27, 24, 30, 13];
let result=arr.reduce((tmp, item, index)=>{
if(index<arr.length-1){
return tmp+item;
}else{
return (tmp+item)/arr.length;
}
});
alert(result);
filter(筛选)
let arr=[12, 5, 8, 99, 27, 24, 30, 13];
let arr2=arr.filter(item=>{
if(item%2==0){
return false;
}else{
return true;
}
});
alert(arr2)
forEach(循环)
let arr=[12, 5, 8, 99, 27, 24, 30, 13];
arr.forEach((item, index)=>{
//console.log('第'+index+'个是:'+item);
console.log(`第${index}个是${item}`);
});
字符串
模板字符串:`` ${}
let x = 1;
let y = 2;console.log(
${x} + ${y} = ${x + y}
)console.log(
${x} + ${y * 2} = ${x + y * 2}
)let obj = {x: 1, y: 2};
console.log(${obj.x + obj.y}
)
…
剩余运算符
function show(a, b, ...c){
console.log(a, b, c);
}
show(12,5,4,8,19,27,36);
//12 5 Array(5) == //12,5,Array[4,8,19,27,36]
数组展开
let arr1=[12,5,8];
function show(a,b,c){
alert(a+b+c);
}
show(...arr1);
let arr1=[12,5,8];
let arr2=[4,5,6];
let arr=[...arr1, ...arr2];
alert(arr);
json展开
let json={a: 12, b: 5, c: 99};
let json2={
...json,
d: 999
};
console.log(json2);
//Object
//Objecta: 12b: 5c: 99d: 999__proto__: Object
面向对象
设计模式就是一种经验。
面向对象核心:对象,设计,prototype,this。
面向对象=属性+方法
概念:
类(class):蓝图,设计图。
实例化:new
实例(instance):由类创建的(new),有功能的。
成员(member):包括的东西(属性+方法)
实例成员----只有在实例上面有的成员。
类成员----(Math.PI) 类上面的成员(无需实例化,直接使用)
面向对象的思想/特性:
- 封装—>(不让别人去修改代码状态)
保护类
数据隐藏–用方法来修改
强制访问权限
便于理解 - 继承—>(在已有的基础上,最大限度的重用父类的代码)
重用代码
无需去修改父类
· 多重继承—可以有多个父类(js不支持)
· 抽象类 - 多态—>()
抽象
简化问题
数据类型检测
typeof 适合用来检测基本数据类型:number string boolean function object undefined
instanceof 实例的具体类型(返回的是true和false)
检测子级类型+父级类型
constructor 返回实例的构造函数
精确类型判断(只检测包括子级,不包括父级)
设计类
设计一个类先想:
自上而下–功能–>方法–>属性
原型(原型链) — prototype
1.干啥的,作用?
给类添加修改数据
这个类所有的实例都有这个东西
2.原理
实例需要某个东西时(属性和方法),首先从自己身上找,如果有直接用,如果没有继续去类身上找,如果还没有去父类上找。
3.用途
给类添加方法
i.添加一些公共的方法。
ii.修补系统的函数 — polyfill
什么是虚拟DOM
通过JS的Object对象模拟DOM中的真实节点对象,再通过特定的render方法将其渲染成真实的DOM节点,好处就是减少DOM操作,提高浏览器的渲染性能。
面向对象的写法:
es5和es6 最大区别 有无专门的类 和专门的构造函数
相同点:添加属性环节相同
- 旧版—ES5(不区分构造函数和类)
function A(){
console.log("ES5被创建了")
this.name="Ben";
this.age=15
}
A.prototype.show=function(){
console.log(this.name,this.age)
}
var a=new A()
console.log(a.name)
console.log(a.age)
a.show()
- 新版—ES6
class A{ // 类 construction(name,age){ //构造函数, console.log("ES6被创建了") this.name=name; //属性 this.age=age } show(){ //方法 console.log(this.name,this.age) } } let a=new A("Ben",18) console.log(a.name) console.log(a.age) a.show()
面向对象的思想/特性:
1.封装—>(不让别人去修改代码状态)
保护类
数据隐藏–用方法来修改
强制访问权限
便于理解
2、继承—>(在已有的基础上,最大限度的重用父类的代码)
重用代码
无需去修改父类
· 多重继承—可以有多个父类(js不支持)
· 抽象类
3、多态—>()
抽象:
简化问题
原型(原型链) — prototype
1、干啥的,作用?
给类添加修改数据
这个类所有的实例都有这个东西
2、原理
实例需要某个东西时(属性和方法),首先从自己身上找,如果有直接用,如果没有继续去类身上找,如果还没有去父类上找。
3、用途???
给类添加方法
i.添加一些公共的方法。
ii.修补系统的函数 — polyfill
this
this受什么影响?
1、 严格模式 ---- 全局函数
2、方法
3、事件
4、定时器
为什么要设计this? ----- 使用当前的实例
js的this为什么乱? — 为了让js更简单易用,js太灵活
操作this:
1、函数的方法:call、apply、bind
fn.call(thisObj,参数1,参数2…)
fn.apply(thisObj,[参数1,参数2…])
//bind–>生成一个新的函数 —> this被绑定了
let show = fn.bind(thisObj)
show()
2、箭头函数 :
箭头函数内部的this永远跟箭头函数外部一致
箭头函数相当于自带一个bind(this)
继承
继承:才是面向对象的精华、目的。
1、继承特别常见
oTxt --> HTMLInputElement —> HTMLElement —> Element —> Node
2、继承的目的:
i.清晰的层次 – 阅读方便 、公共操作/属性
ii.功能得到重用(属性、方法)
iii.使用多态来简化程序
3、适用场景:
i.拥有明确的、合理的父子级关系
ii.子类能够完全覆盖父类
4、概念:
1、父类:被继承的类(基类、超类 )
2、子类:通过继承出来的新的类(派生类,衍生类)
3、继承:(派生)
4、抽象类:本身无法直接实例化、仅仅作为父类使用(公共的功能) JS本身不支持抽象类
5、继承的写法:
//ES5 写法
function A (user){
this.user=user+"a"
}
A.prototype.show=function(){
alert(this.user)
}
funtion B(user,age){
}
let b=new B("",12)
alert(b.user)
// ES6 统一
class A{
construction(name){
this.name=name
}
show(){
alert(this.name)
}
}
class B extends A{
construction(name,age){
super(name) //继承父类的属性
this.age=age
}
showage(){
alert(this.age)
}
}
let b=new B("aaa",19)
alert(b.show)