JS 源码学习

170 阅读2分钟

前言

或许不安或许迷惑,但迷雾遮挡不住前方的光亮,有梦可待。

这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

1.封装原生XMLHttpRequest请求

   function createXMLHttp(baseUrl){
     //低版本IE兼容
     var XmlHttp=window.XMLHttpRequest ?new XMLHttpRequest():ActiveXobject('Msxml12.XMLHTTP')
     //默认请求 协议 IP port
     var defaultURL=baseUrl?baseUrl:'http://localhost:3000';
     return{
      //method默认GET  
        //url--接口名称/data/query
        //data--发送的数据
        //success--成功回调函数,error--失败回调函数
        //用的是es6解构
        
        sendRequest({method='GET',url,data=null,success.error}){
        XmlHttp.open(method,defaultURL+url);
        if(method.toUpperCase()=="GET"){
          XmlHttp.send();
        }else{
           XmlHttp.setRequestHeader('Content-Type','application/json')
           XmlHttp.send(data);
        }
       XmlHtpp.onreadystatechange=function (resp){
       if(XmlHttp.readyState==4&&XmlHttp.status==200){
             success(XmlHttp.responseText,resp);
       }
       }
        XmlHttp.onerror=function(err){error(err)}
        }
     }
   
   }

2.简易node服务端(express)

   var express=require("express")//加载依赖包
   var bodyParser=require('body-parser')//body解析
    var multiparty=requier('multiparty')//从node_modules
    var app=express();
    var path=require('path')//node自带
    //OPTIONS -- 若有跨域情况,浏览器会先发送试探请求
    var allowCrossDomain=function(req,res,next){
    res.setHeader('Access-Contorl-Allow-Origin','*')//允许请求的源头
    res.setHeader('Access-Control-Allow-Methods','GET,POST,OPTIONS,PUT,DELETE')//允许任何方法
    res.setHeader('Access-Control-Allow-Headers','X-Requested-with,content-type,x-Session-Token')//允许任何类型
    next();//下一步
    };
    
    app.use(allowCrossDomain)//运用跨域的中间件
    app.use(bodyParser.json())//创建application/json解析
    app.use(bodyParser.urlencoded({extend:true}))// 创建 application/x-www-form-urlencoded 解析
    var arr = [1,2,3]
//http://localhost:3000/
//接口实现
//请求方式 get post put delete
//"/data/query"  接口地址
//req==request, res==response
app.get("/", function(req, res){
	res.send('index')
})
app.get("/api/data/query", function(req, res){
	console.log(req.body, req.query.name)
	res.send(JSON.stringify(arr));
})

// 规定了data/后面就是参数
app.get("/api/data/:name-:age", function(req, res){
	console.log(req.body, req.query, req.params)
	res.send(JSON.stringify(arr));
})

//post  put
app.post("/api/data/add", function(req,res){
	console.log(req.body, req.query)
	res.send(JSON.stringify(arr));
})

//formdata数据格式
app.post("/api/data/form", function(req, res) {
    var form = new multiparty.Form();
    form.parse(req, function(err, fields, files) {
           console.log(req.body, req.query, fields)
		   res.send(JSON.stringify(fields));
    })
})

//跨域第三种  jsonp
app.get("/api/jsonp", function(req, res){
    var data = {name: "jsonp数据"} //返回数据
    data = JSON.stringify(data); //转字符串
    //var callback = `handleResponse(${data})`;
    var callback = `${req.query.callback}(${data})`; //函数名+数据
    console.log(callback)
    res.send(callback);
})

let username = "admin";
let passord = "123789";
let dataList = [
    {name: "xxxx", address: "yyy", city: "beijin"}
]
app.post("/api/login", function(req, res){
    //判断用户参数是否与上面的匹配
    //post/put---请求体----req.body
    //get----req.query
})


app.listen(3000, function(){console.log("Server started on port 3000.")});
    
    
   

3.代理模式

   //声明女孩对象
   var girl=function(name){
     this.name=name;
     
   };
   //声明男孩对象
   var boy=function(girl){
     this.girl=girl;
     this.sendGift=function(gift){
       console.log('Hi'+girl.name+",男孩送你一个礼物"+gift)
     }
   }
   //声明代理对象
   var proxyObj=function(girl){
      this.sendGift=function(gift){
      var b=new boy(girl);
      b.sendGift(gift);//替dudu送花
      }
   }
   var proxy=new proxyObj(new girl('花花'))
    proxy.sendGift('999朵玫瑰')

4.单例模式

class Store{
  action(){
  console.log('vue store.')
  }
}
// 定义一个静态的方法,将方法挂载到class上面,无论SingleObject被new多少个,getInstance的方法只有一个
Store.getInstance=(function(){
   let instance
   return function(){
      if(!instance){
      instance=new Store();
      }
      return instance
   }

})()

// js中的单例模式只能靠文档去约束,不能使用private关键字去约束
// 测试:注意这里只能使用静态函数getInstance,不能使用new Store()
let obj1=Store.getInstance()
obj1.action()
let obj2=Store.getInstance()
  obj2.action()
  // 单例模式(唯一的),每次获取的都是一个东西,所以他两相等,否则就不是单例模式
console.log(obj1 === obj2) //true

5.工厂模式

    //function
   var MobileFactory=(function(){
     var Mobile=function(name,model){
     this.model=model;
     this.name=name;
     };
     Mobile.prototype.play=function(){
     console.log('Model:'+this.name+"-"+this.model)
     }
     return function(name,model){
     return new Mobile(name,model)
     }
   
   })()
   var p6=MobileFactory('iphone','6')
   var px=MovileFactory('iphone','x')
   p6.play()
   px.play()
 
  class Product{
  constructor(name,model){
     this.name=name;
     this.model=model;
  
  }
  play(){
  console.log('Mobile:'+this.name+'-'+this.model)
  }
  }
   class FactoryCreator{
     create(name,model){
     return new Product(name,model)
     }
   }
   let creator=new FactoryCreator()
   // 通过工厂省城product的实例
   let p=creator.create('iphone','6')
   p.play();
   let p2=creator.create('iphone','7')
   p2.play()

6.观察者

   class Subject{//发布者
     counstructor(){//构造器
     this.subs=[]; //订阅列表--数组
     }
     addSub(sub){//方法
     this.subs.push(sub);
     }
     notify(food){//通知订阅者
     this.subs.forEach(sub=>{
     sub.update(food);
     })
     }
   }
   class Observer{//订阅者
     constructor(name,food){//订阅外卖名字
      this.name=name;
      this.food=fooe;
}
updata(food){
  if(food===this.food){
      console.log(this.name + "的外卖:"+food);
  }
}
   
   
   }
  var subject = new Subject(); //实例化发布者
  var tom = new Observer("tom","地三鲜"); //实例化订阅者
  var jack = new Observer("jack","红烧肉");
  //目标添加观察者了
  subject.addSub(tom);
  subject.addSub(jack);
  //目标发布消息调用观察者的更新方法了
  subject.notify("地三鲜");
  subject.notify("红烧肉");

7.适配器

   class IphoneX{
     constructor(){
     this.interface='平接口type-c'
     }
   
   }
   
   class IphoneAdapter{
    //oldInter旧接口,newInter新接口
     constructor(oldInter,newInter){// 构造函数
  
        this.phone=new IphoneX() // 初始化实例
        this.oldInter=oldInter
        this.newInter=newInter
        
     
     }
     getOldInter(){
      return this.oldInter
     }
     translate(phone,newInter){//模拟转接头
     //把平果接口线路连接到新接口上
     var _newInter='新接口'console.log(`${phone.interface}---->>${newInter}`)
       return _newInter;
      
     }
     getNewInter(){//覆盖
     let newInterface=this.translate(this.phone,this.newInter)
     return newInterface;
     
     }
   }
   let adapter = new IPhoneAdapter('平接口', '圆接口')
let res = adapter.getNewInter()
console.log(res) // 圆接口

res = adapter.getOldInter()
console.log(res) // 平接口

9.装饰器

class Circle {
	draw() {
		console.log('我要画一个圆')
	}
}

class CircleDecorator {
	constructor(circle) {
		this.circle = circle
	}
	draw() {
		this.circle.draw()
		this.setBorder(circle)
	}
	setBorder(circle) {
		console.log('加上边框')
	}
} 
// 想引用某个类的时候将他实例化,以参数的形式进行传递进去
let circle = new Circle()
circle.draw()
console.log('+++++')
let dec = new CircleDecorator(circle)//把原实例对象传入到一个新装饰对象中
dec.draw()

总结

努力学习