代理得demo
// 代理是什么呢?
// 比如下面,通过proxy这个中间人来获取对象里的内容,中间人就是代理
// 首先定义一下对象
let user={
name:"小明",
age:10
}
// 下面就是使用代理
// 首先 let a = new Proxy(obj,{}) obj代表代理得目标对象
// 后面得对象代表得是使用get方法和set来获得值和设置值
let a = new Proxy(user,{
// get方法里面第一个参数传代理目标对象target也就是上面的user,第二个代表user里面的属性name,age
get(target,attr){
console.log(target); // user
console.log(attr); // age,因为下面调用a的时候,使用的是age属性
// return里面的内容就是如下面a.age的时候 产生的东西
// 就是a.age = target[attr]?target[attr]:null
return target[attr]?target[attr]:null
},
// set方法里面第一个参数传代理目标对象target,第二个代表属性,第三个代表设置得值
set(target,attr,value){
target[attr] = value
}
})
let age = a.age
再如
const obj = {
a: 10
}
let handler = {
get: function(target, name){
console.log('test: ', target, name)
// test: {"a":10} a
// test: {"a":10} b
return name in target ? target[name] : 37
}
}
let p = new Proxy(obj, handler)
console.log(p.a, p.b) // 10 37
那么使用代理得好处就是在进行获取值和设置值得时候,就可以做限制
使用代理写类似jsx语法
var DOM = new Proxy({},{
get(target,attr){
var dom = document.createElement(attr)
return function (attrs,...children){
for ( i in attrs) {
dom.setAttribute(i,attrs[i]) // 把属性添加到标签里
}
for (let i = 0; i < children.length; i++) {
if (typeof children[i] == 'string') {
children[i] = document.createTextNode(children[i])
}
dom.appendChild(children[i])
}
return dom
}
}
})
// DOM.div后拿到的就是那个返回的函数
var d = DOM.div({id:"aa"},"你好","嗯嗯")
document.body.appendChild(d)
var u = DOM.ul({id:"bb"},DOM.li({"class":"li"})) // 还可以在代理对象里调用代理对象方法,类似jsx
document.body.appendChild(u)
模块化
补充导入导出,html文件中使用模块化
// 导入
<body>
<script src="./index.js" type="module" charset="utf-8"> </script>
<script type="module">
import {b} from "./index.js"
console.log(b);
</script>
</body>
// 导出
let b={b:20};
export {b};
promise派生
// 通过继承来写自己得promise
class aa extends Promise{
success(resolve,reject){ // 其实就是传一个 success 方法来加强then方法
this.then(resolve,reject)
}
fail(reject){
this.catch(resolve,reject)
}
}
var aaa = new aa(function (resolve,reject) {
if (true) {
resolve("我是对的")
} else {
reject("错误")
}
})
aaa.success(function (res){ // 调用success就相当于调用then
console.log(res);
})
console.log(aaa);
简单实现promise
实现promise原理:
其实就是首先定义两个数组,这两个数组的作用分别就是存放执行then的回调函数和catch的回调函数。再使用then方法的时候,就会把执行then的回调函数和catch的放到数组里面。然后比如执行then方法,那么在resolve方法里,一个个循环把数组里面的函数执行。
上面是promise的执行流程,下面详细解析
首先比如下面代码是使用class写的,当new这个对象的时候,就会执行构造函数,所以在构造函数里面写一个new Promise成功之后的回调函数,这个回调函数里面写判断什么时候执行resolve(),rejected(),所以这个构造函数里面的回调函数需要传两个函数参数,分别是resolve,rejected
然后再回调函数里,比如判断为true时执行resolve,这里也就是把注册再数组里,为使用promise成功的函数一个个执行出来。所以,new primose的之后,会执行上面这些东西,然后再new 出来的primise对象执行then
然后再new 出来的primise对象执行then,then里面会放一个回调函数,这个回调函数就是放到数组里的,最后被执行的回调函数。
当new promise的时候,会执行构造函数,会执行new promise后的回调函数,回调函数里面的参数是resolve函数,用来执行存放再数组里面的函数,回调函数是判断是执行resolve函数,还是reject,所以传promise里面的resolve和reject
再没有使用then函数时,数组是空的
当使用then方法后,就会执行把函数注册到数组里,然后执行数组里面的函数
class NoPromise{
constructor(fn){
this.successList = []; // 第一步,定义数组
this.failList = [];
fn(this.resolveFn.bind(this),this.rejectFn.bind(this)) // 第四步,定义一个回调函数作为判断是执行resolve还是,并且需要绑定当前this(new出来的对象),否则指向window,并且执行resolve
}
then(successFn,failFn){ // 第二步,把把then里面的函数放到数组里
console.log("then被执行了");
if (typeof successFn == 'function') { this.successList.push(successFn) }
if (typeof failFn == 'function') { this.failList.push(failFn) }
}
catch( failFn ){
if (typeof failFn == "function") { this.failList.push(failFn) }
}
resolveFn(res){ // 第三步,定义执行数组里的函数的函数
console.log("resolveFn我被执行了1111111");
console.log(this.successList);
this.successList.forEach(function (item,index){
console.log("resolveFn我被执行了");
item(res)
})
}
rejectFn(res){
this.failList.forEach(function (item,index){
item(res)
})
}
}
let fn1 = function ( resolve, reject){ // 这就是回调函数,用来判断
console.log("fn被执行啦");
setTimeout(function (){
if (true) {
resolve("成功")
}else{
reject("失败")
}
},1000)
}
let p1 = new NoPromise( fn1 ) // 使用第一步,传一个new promise的后的回调函数
console.log(p1);
p1.then(function (res){ console.log(res);}) // 传一个放到数组里的函数,也是then之后的回调就回调的函数
p1.catch(function (res){ console.log(res);})