递归函数 :函数内部自调用
栈:存储基础数据类型以及指定代码的环境
堆:存储引用数据类型
递归函数 必须要有跳出循环的条件
求和: 1+2+3+...+100
var sum = 0
for (let i = 0; i <= 100; i++) {
sum+=i
}
console.log(sum);
function sum(a){
if (a == 1) {
return 1
}else{
return a+sum(a-1)
}
}
sum(100)
console.log(sum(100));
斐波那契数列:兔子数列 0,1,1,2,3,5... 计算第21位的值
function fn(n){
if (n===1) {
return 0
}else if(n===2){
return 1
}else{
return fn(n-1)+fn(n-2)
}
}
console.log(fn(21));
function fn(n,curr=0,next=1){
if (n===1) {
return curr
}else{
return fn(n-1,next,curr+next)
}
}
console.log(fn(21));
有64个格子,第一个格子放一粒麦子,第二个放2粒,第三个放4粒...每个格子都是前边的两倍。一共有多少粒?
function sum(a){
if (a===1) {
return 1
}else{
return Math.pow(2,a-1)+sum(a-1)
}
}
console.log(sum(64));
箭头函数
var a = () => {console.log(1);}
a()
方法只有一句话时 {}可以省略 if() 后面只有一句话时 {}也可以省略
if(true) console.log(2);
var a = ()=> console.log(3);
a()
参数有且只有一个 ()可以省略 没有参数 ()必须有
var a = r => console.log(r);
var arr = [1,2,3,5]
var arr2 = arr.map(r=>r*3)
var arr2 = arr.map(function(r){
return r*3
})
console.log(arr2);
方法只有一句 return可以省略
var arr2 = arr.map(r=>r*3)
箭头函数没有this指向 它的this 指向父级
document.getElementById("box").onclick = function(){
}
document.getElementById("box").onclick = ()=>{console.log(1);}
var obj = {
// fn:function(){console.log(this);}
fn:()=>{console.log(this);}
}
obj.fn()
function Fun(name){
this.name = name
// this.fn = function(){console.log(this);}
this.fn = ()=>{console.log(this);}
}
var pzj = new Fun("彭忠杰")
pzj.fn()
Fun.prototype.aa = ()=>{
console.log(this);
}
pzj.aa()
setTimeout(function(){
console.log(this);
})
setTimeout(() => {
console.log(this);
});
var c = ()=>{console.log(this);}
箭头函数没有this 不能被new 没有原型链
深拷贝和浅拷贝
浅拷贝 :只拷贝一层 深层次对象只拷贝地址
let obj = {
id:1,
name:"赵君",
num:{
yc:"1000w"
},
sex:["男","女"],
time:new Date,//标准时间 标准时间的字符串
Reg:/^\d+$/,
fn:()=>{
console.log(1);
}
}
let a = obj
a.name = "施强"
obj.id = 5
console.log(obj);
console.log(a);
深拷贝 每一层都拷贝
let obj1 = {
id:2,
name:["赵君","aa"]
}
let obj2 = {
id:obj1.id,
name:obj1.name
}
obj2.name = "施强"
console.log(obj1);
console.log(obj2);
1.ES6 Object.assign() 用于将所有可枚举的属性值从一个或多个对象分配到目标上
let a = {}
Object.assign(a,obj)
a.name = "施强"
console.log(a);
console.log(obj);
2.JSON 保留原数据格式 简单粗暴 弊端:转换时间
let obj3 = JSON.stringify(obj)
console.log(obj3);
obj3 = JSON.parse(obj3)
console.log(obj3);
3.递归
let arr = [2, "aa", {
a: "aa"
}, {
a: {
a: "daa"
},
s: "ss"
}]
function deepc(e) {
var a;
console.log(typeof e);
if (typeof e === 'object') {
// 判断是否为数组
if (Array.isArray(e)) {
a = []
for (let i in e) {
a.push(deepc(e[i]))
}
} else if (e === null) {
// 判断是否为null
a = e
} else if (e.constructor === RegExp) {
// 判断是否为正则
a = e
} else if (e.constructor === Date) {
// 判断是否为时间类型
a = e
} else if (e.constructor === Function) {
// 判断是否为函数
a = e
} else {
// 判断是否为对象
a = {}
for (let i in e) {
a[i] = deepc(e[i])
}
}
} else {
// 基本数据类型直接赋值
a = e
}
return a
}
var c = deepc(obj)
c.id = 8
console.log(c);
console.log(obj);
object新增方法
defineProperty
Object.defineProperty(obj,prop,descriptor) 重新定义对象属性
var obj = {
name: "Jandy",
age: 18,
tag: "离异带俩娃"
}
obj.name = "sandy"
Object.defineProperty(obj, "tag", {
value: "孩子没判她",
writable: false //禁止修改 默认值为true
})
console.log(obj);
obj.tag = "?"
console.log(obj);
Object.defineProperty(obj, "height", {
value: "2m",
enumerable: false, //禁止使用for in 遍历 默认值false
configurable: false //禁止删除 默认为false
})
for (let i in obj) {
console.log(obj[i]);
}
如何删除对象中的属性
delete obj.height
console.log(obj.height);
delete obj.height
delete obj.name
console.log(obj.height);
console.log(obj.name);
symbol
ES6中新增的数据类型 存储关键数据 或者 服务器数据
let a = 1
let b = "1"
console.log(a == b); //true
console.log(a === b); //false
唯一数据
let c = Symbol("1")
let d = Symbol("1")
console.log(c == d);
console.log(c === d);
获取Symbol中的值 description
console.log(c.description === d.description);
console.log(typeof c);
for 通过for来指定一个Symbol空间
let e = Symbol.for("aa")
let f = Symbol.for("aa")
console.log(e === f);
keyFor 通过变量名 反向查找Symbol数据 只有for声明出得变量才可以使用
console.log(Symbol.keyFor(e));
console.log(Symbol.keyFor(f));
console.log(Symbol.keyFor(c));
promise
ES6 新增的一个构造函数 创造了一个promise实例对象
代表了将来要发生的事情 用来传递异步操作
const pro = new Promise(function (resolve, reject) {
// 回调函数
let a = 0 //初始状态
console.log(a);
if (true) {
//成功状态 res
a = 1
resolve(1)
} else {
// 失败状态 rej
a = 5
reject(2)
}
})
console.log(pro);
1.pending 初始状态
2.fulfilled 成功状态
3.reject 失败状态
then catch 原型链上 链式编程 .then().catch().then()
pro.then(function(res){
// 成功值
console.log(res);
}).catch(function(rej){
// 失败值
console.log(rej);
})
pro.then(res=>console.log(res)).catch(rej=>console.log(rej))
function(){function(){function(){}}} //嵌套函数
链式编程 后面的回调函数可以使用上一次返回结果
pro.then(r=>{
console.log(r); //1
return r*3
}).then(r=>console.log("r",r)).then(r=>console.log("r",r))
pro.then(r => {
console.log(r); //1
return r * 3
}).then(r => {
console.log("r", r) //3
return Promise.resolve(4)
}).then(r => {
console.log("r", r) //4
return Promise.reject(5)
}).then(r => {
console.log("r", r);
// 当返回reject失败,后面的then都不触发 只触发catch
}).catch(e => console.log("e", e)) //5
地狱回调
setTimeout(() => {
console.log("武林要以和为贵!");
setTimeout(() => {
console.log("要讲武德!");
setTimeout(() => {
console.log("不要搞窝里斗!");
}, 1000);
}, 1000);
}, 1000);
Promise解决方式
function fn(str) {
var p = new Promise(function (r, e) {
// 处理异步任务
setTimeout(() => {
if (true) r(str)
else e("操作失败")
}, 1000);
})
return p
}
fn("武林要以和为贵!").then(r => {
console.log(r);
return fn("要讲武德!")
}).then(r => {
console.log(r);
return fn("不要搞窝里斗!")
}).then(r=>console.log(r))
Promise 封装ajax
function getData(url,type,data){
let pro = new Promise(res,rej){
// 初始化
let xHttp = new XMLHttpRequest()
xHttp.onreadystatechange = function(){
if (this.readyState !==4 ) {
return
}
if(this.status === 200){
// 成功
res(this.response)
}else{
// 失败
rej(new Error(this.statusText))
}
}
}
xHttp.open(type,url)
xHttp.responseType = "json"
xHttp.setRequestHeader("Accept","application/json")
xHttp.send(data)
}
return pro
getData("xxxx","post",{name:"pzj"})