手写 及 小案例

294 阅读2分钟

手写call

function fn(){
    console.log(this)
}
var obj = {
    a:12,
    b:13,
    f:fn,
}
Function.prototype.myCall = function myCall(context,...arg){
    //this -----> fn
    context = context || window;//给context一个默认值,传入就用传入的,没穿就用window;
    let a = Symbol(); //产生一个唯一的不会重复的值
    context[a] = this; //context[a]---->fn
    let res = context[a](...arg); //让fn执行
    delete context[a]; //删除增加的属性
    return res;
}
fn.myCall(obj,6,6,6)//让fn执行,fn中的this指向obj,把6,6,6,传给fn

手写apply

function fn(){
    console.log(this)
}
var obj = {
    a:12,
    b:13,
    f:fn,
}
Function.prototype.myApply = function(context,arg){
    arg = arg || [];
    context = context || window;
    let a = Symbol();
    context[a] = this;
    let res = context[a](...arg);
    delete context[a];
    return res;
}
fn.myApply(obj,[6,6,6])

手写bind 未考虑new

function fn(){
    console.log(this)
    return 23333
}
var obj = {
    a:12,
    b:13,
}
Function.prototype.myBind = function(context,...arg){
    var _this = this;
    return functioni(...arg){
        return _this.apply(context,arg.concat(ary)
    }
}
var f2 = fn.myBind(obj,6,6,6)

选项卡

/*

  • 获取操作的元素 tab body
  • 清除类名的功能
  • 循环绑定点击事件

*/

// css样式
<style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }

        .box {
            width: 600px;
            margin: 30px auto;

        }

        .tab_box {
            border: 1px solid salmon;
            display: flex;
        }

        .tab {
            flex: 1;
            line-height: 50px;
            text-align: center;
            font-size: 20px;
            cursor: pointer;
            user-select: none;
        }

        .tab:nth-child(2) {
            border: 1px solid salmon;
            border-bottom: none;
            border-top: none;
        }

        .tab.current {
            /*同时又 tab 和 current者两个类名的元素才会有对应的样式 */
            background: salmon;
            color: #fff;
        }

        .body_box {
            width: 600px;
            height: 300px;
            border: 1px dashed salmon;
            border-top: none;
            overflow: hidden;
            box-sizing: border-box;
        }

        .body {
            width: 600px;
            height: 300px;
            text-align: center;
            line-height: 300px;
            font-size: 50px;
            display: none;
        }

        .body.current {
            display: block;
        }
//body
<body>
    <div class="box" id="box">
        <ul class="tab_box">
            <li class="tab current">css</li>
            <li class="tab">JS</li>
            <li class="tab">HTML</li>
        </ul>

        <ul class="body_box">
            <li class="body current">CSS基础</li>
            <li class="body">JS基础</li>
            <li class="body">HTML基础</li>
        </ul>
    </div>
</body>
//JS样式
function Tab(idSelector){
    this.box = document.querySelector(idSelector);
    this.tabs = document.getElementsByClassName('tab');
    this.bodys = document.getElementsByClassName('body');
    this.mpaBind();
  Tab.prototype.mapBind = function(){
      for(let i =0;i<this.tabs.length;i++){
          this.tabs[i].onclick = ()=>{
              this.clerClass();
              this.tabs[i].className = 'tab current';
              this.bodys[i].className = 'bodys current';
          }
      }
  }
  Tab.prototype.clearClass = function(){
      for(var i = 0;i<this.tabs.length;i++){
          this.tabs[i].className = 'tab';
          this.bodys[i].className = 'body';
      }
  }
  var tab = new Tab('#box')
}