bind实现

一、原生js实现Bind

bind的三个特点

(1)保存this,返回新的函数

(2)可以传入参数

(3)一个绑定函数也可以使用new操作符创建对象,这种行为就像把原函数当成构造器,提供的this值被忽略,同时调用时的参数被提供给模拟函数

根据三个特点,分为3个步骤来实现bind

(1)保存this,返回新的函数

 var foo={
    value:1
  };
  function bar(){
    console.log(this.value)
  }
    Function.prototype.bind0=function(context){
      var self=this;
      console.log(self);//在这里this是bar
      return function(){
        self.apply(context)  //执行bar()函数把里面的this 换为context的值
      }
    }
    //使用bind
  bar.bind(foo)();
  //使用自己的Bind0
  bar.bind0(foo)();

输出结果

 自己实现的Bind也输出了1,并且保存的this值为Bar().context 为foo, self.apply(context)即执行bar函数,并把this 改为foo, this.value===foo.value,输出值为1

(2)可以传入参数

 function bar(name,age){
   console.log(name);
    console.log(age);
    console.log(this.value)
  }
    Function.prototype.bind0=function(context){
      var self=this;
    //  console.log(self);//在这里this是bar
      var args=Array.prototype.slice.call(arguments,1);
      return function(){
        var args1=Array.prototype.slice.call(arguments,0);
        self.apply(context,args.concat(args1))  //执行bar()函数把里面的this 换为context的值
      }
    }
    //使用bind
  bar.bind(foo,"lily")(36);
  bar.bind(foo,"lily",36)();
  //使用自己的Bind0
  bar.bind0(foo,"lily")(36);
  bar.bind0(foo,"lily",36)();

 输出结果:

分析:

 var args=Array.prototype.slice.call(arguments,1);

 slice()方法数组和字符串也有,都是截取字符串或者数组,本次选用数组的slice 。运用call方法把slice的this值变为类数组arguments,arrayObj.slice(start, [end]),这里的第二个参数1,即为给slice传入的参数,即从下标截取到结束。

本题即为除保存的this值外传入的其他参数。

args1是是bind返回的函数结束的参数,所以直接从0开始截取。

(3)一个绑定函数也可以使用new操作符创建对象,这种行为就像把原函数当成构造器,提供的this值被忽略,同时调用时的参数被提供给模拟函数

传入的参数依然接收,但是this值并没有改变,所以this.value输出undefined

 Function.prototype.bind0=function(context){
    var self=this;
    var args=Array.prototype.slice.call(arguments,1);
   var fResult= function(){
      console.log(this);//没有fResult接收匿名函数时,这个this这是一个空对象,如果把这里面的this 变为bar ,则可以实现obj1.sex为女this
      console.log(self);
      var args1=Array.prototype.slice.call(arguments,0);
      self.apply(this instanceof self?this:context,args.concat(args1));//函数把里面的this 换为context的值
    };
   fResult.prototype=self.prototype;
    return fResult;
}   //使用bind
 var bindfoo= bar.bind(foo,"lily");
var obj=new bindfoo(36);
console.log(obj.sex)
  //使用自己的Bind0
  var bindfoo1= bar.bind0(foo,"lily");
  var obj1=new bindfoo1(36);
  console.log(obj1.sex)

 输出结果:

分析:主要添加的this的判别, this是bar()函数的实例,则具备bar对象的原型,如果不是则依旧传入context

二、零碎知识点总结

1、判断一个字符串中是否有汉字

(1)用正则表达式判断

 var reg = new RegExp("[\\u4E00-\\u9FFF]+","g");

(2)JavaScript charCodeAt() 方法

charCodeAt() 方法可返回指定位置的字符的 Unicode 编码。这个返回值是 0 - 65535 之间的整数。如果大于255,则是汉字。

语法:   stringObject.charCodeAt(index)

例题:如果第二个参数 bUnicode255For1 === true,则所有字符长度为 1
否则如果字符 Unicode 编码 > 255 则长度为 2

function strLength(s, bUnicode255For1) {
    if(!bUnicode255For1){
    var strlen=0;
  for(var i = 0;i < s.length; i++){
    if(s.charCodeAt(i) > 255){ //如果是汉字,则字符串长度加2
      strlen += 2}
    else
    {strlen++;}
  }
    return strlen; }
else{ return s.length; }
}

2、字符串和数组的方法区别

字符串常用方法:

名称语法返回值
sliceslice(start,end)提取字符串的片断,并在新的字符串中返回被提取的部分。
splitsplit(",")把字符串分割为字符串数组。
substrsubstr(index,len)从指定位置开始截取给定长度的字符串,返回此新的字符串,如果没有指定 length,那么返回的字符串包含从 startstringObject 的结尾的字符。
substringsubstring(start,end)截取子字符串
concat
concat(stringX,stringX,...,stringX)
连接字符串,返回连接后的字符串

        

结论:上述字符串方法均不改变原字符串

数组常用方法

名称语法返回值
concat
concat(arrayX,arrayX,......,arrayX)

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

poppop()删除并返回数组的最后一个元素
push
push(newelement1,newelement2,....,newelementX)
向数组中压入数据,返回新数组的长度
slice
slice(start,end)
从某个已有数组中返回选定的元素
splice
splice(index,howmany,item1,.....,itemX)
从数组中添加或删除项目,返回被删除的项目

结论:数组concat方法不改变原数组,Push和pop的返回值分别为新数组的长度和删除的元素,改变了原数组。(补充:shift也会改变原数组)

slice不改变原数组,splice增加时不返回元素,替换时返回替换的元素,并且改变原数组

3、用户输入内容,检测和json数据中的某一项是否对应。

 <ul id="list">
                <li id="code0"><span>Course Code</span><input class="code0" placeholder="Please enter your Course code"></li>
                <li id="code1"><span>Course Code</span><input class="code1" placeholder="Please enter your Course code"></li>
                <li id="code2"><span>Course Code</span><input class="code2" placeholder="Please enter your Course code"></li>
                <li id="code3"><span>Course Code</span><input class="code3" placeholder="Please enter your Course code"></li>
                <li id="code4"><span>Course Code</span><input class="code4" placeholder="Please enter your Course code"></li>
            </ul>

在输入enter键时候,判断判断所填入内容和json内容sh是否一致

var database0 = [{
                Coursecode: "WEB122",
                Coursetitle: "Intro to programming",
                Credit: 3
            },
            {
                Coursecode: "WEB222",
                Coursetitle: "Web Programming Principles",
                Credit: 3
            },
            {
                Coursecode: "WEB322",
                Coursetitle: "Object Oriented Programming",
                Credit: 3
            },
            {
                Coursecode: "WEB422",
                Coursetitle: "Principles",
                Credit: 3
            },
            {
                Coursecode: "WEB522",
                Coursetitle: "Math",
                Credit: 3
            },
        ];
 var course = document.getElementById("list")
        course.onkeyup=function(e){   
            console.log(e.target);
            var keyNum=window.event ? e.keyCode :e.which;  
       //判断如果用户按下了回车键(keycode=13)
      if(keyNum==13){
            var num = e.target.value;   
          for(var i=0;i<database0.length;i++){
             if(database0[i].Coursecode==num){
                 console.log(num)
                 return ;
              }else{  }
          }
          alert("Please re-enter a valid course code")

      }else{
      }        
        };

用户按下enter键,会判断是否一致,出现问题,如果一致,会弹出4次不一致,一次无反应。检查后发现,alert不应该写在for循环的里面,而应该写在外面。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
call、apply和bind都是用来改变函数中的this指向的方法。其中,call和apply可以直接调用函数并传递参数,而bind则返回一个新的函数,需要手动调用。 具体实现方案如下: - call的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数。 3. 结束调用后,删除该属性。 - apply的实现: 1. 给想要绑定的对象设置一个属性,并将该属性指向需要调用的函数。 2. 使用该对象调用函数,并传递参数数组。 3. 结束调用后,删除该属性。 - bind实现: 1. 创建一个新的函数,并将原函数作为其中的属性保存起来。 2. 当新函数被调用时,将之前绑定的对象作为this,并传递参数。 3. 返回新函数供后续调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [如何实现call、apply、bind](https://blog.csdn.net/XIAO_A_fighting/article/details/116701887)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [原生JS实现 call apply bind](https://download.csdn.net/download/weixin_38628990/14046564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值