资讯专栏INFORMATION COLUMN

手动实现es5中的bind方法

williamwen1986 / 519人阅读

摘要:前言的指向在中一直是个谜一样的存在,但是很多地方又会用到,所以理解和使用非常重要,关于的理解这篇文章不做介绍,因为这篇的目的是改变的指向。改变的指向有三种方法,,,。

前言

this的指向在javascript中一直是个谜一样的存在,但是很多地方又会用到this,所以理解和使用this非常重要,关于this的理解这篇文章不做介绍,因为这篇的目的是改变this的指向。

改变this的指向有三种方法,call,apply,bind。下面先介绍下这三种方法

改变this指向 call
var a = {
    name:"aaa",
    say(type){
        console.log(type,this.name);
    }
}
a.say("at");//at aaa
var tn = {name:"ttt"};
a.say.call(tn,"tt")//tt ttt

可以看到通过call,say方法中的this指向了tn,传参的方式的列举

apply
var a = {
    name:"aaa",
    say(type){
        console.log(type,this.name);
    }
}
a.say("at");
var tn = {name:"ttt"};
a.say.apply(tn,["tt"])

可以看到通过apply,say方法中的this指向了tn,传参的方式是数组

bind

bind也能改变this的指向,不过和call,apply不同的地方在于,bind只改变this,不会指向函数

var a = {
    name:"aaa",
    say(type){
        console.log(type,this.name);
    }
}
var tn = {name:"ttt"};
var b = a.say.bind(tn);
b();//ttt

bind 改变this,也是能够继承原型链的,看下下面的代码

var to = {name:"to",color:"red"};
function Animal(){
    console.log(`name:${this.name}...color:${this.color}`);
}
Animal.prototype.say = function(){
    console.log(`say..name:${this.name}...color:${this.color}`);
}
var Cat = Animal.bind(to);
Cat();//name:to...color:red
var cat = new Cat();// name:undefined...color:undefined
cat.say();//say..name:undefined...color:undefined

因为cat是Cat的实例,Cat是改变了this的Animal,所以cat也是Animal的实例,但是this是指向cat的,所以this.name是undefined

实现bind
Function.prototype.bind = function(obj){
    const args = Array.prototype.slice.call(arguments,1);//保留bind时的参数
    const that = this;
    const bound =  function(){
        const inArgs = Array.prototype.slice.call(arguments);//执行bind的函数时的参数
        const newArgs = args.concat(inArgs);//组装参数
        that.apply(obj,newArgs);//执行bind的函数
    }
    //继承prototype--寄生组合式继承
    function F(){};
    F.prototype = that.prototype;
    bound.prototype = new F();
    return bound;
}

然后执行上面的代码

Cat();//name:to...color:red
var cat = new Cat();//name:to...color:red
cat.say();//say..name:undefined...color:undefined

不过第二行和原生的bind还是有点区别的,这里还是记住了之前的bind的对象,原生的不知道为啥是undefined

面试题

实现es5中的bind方法,使得下面的代码输出success

function Animal(name,color){
    this.name = name;
    this.color = color;
}
Animal.prototype.say = function(){
    return `i am a ${this.color} ${this.name}`
}
const Cat = Animal.bind(null,"cat");
const cat = new Cat("white");
if(cat.say() === "i am a white cat" && cat instanceof Cat && cat instanceof Animal){
    console.log("success")
}

加上上面的bind实现,咦??没有出现success??为什么?
分析一下代码,bind的第一个参数是null??null的时候应该默认为this,修改代码如下

Function.prototype.bind = function(obj){
    const args = Array.prototype.slice.call(arguments,1);//保留bind时的参数
    const that = this;
    const bound =  function(){
        const inArgs = Array.prototype.slice.call(arguments);//执行bind的函数时的参数
        const newArgs = args.concat(inArgs);//组装参数
        const bo = obj || this;
        that.apply(bo,newArgs);//执行bind的函数
    }
    //继承prototype--寄生组合式继承
    function F(){};
    F.prototype = that.prototype;
    bound.prototype = new F();
    return bound;
}

输出success
完美~~~
撒花~~~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99783.html

相关文章

  • javascript系列--this指向和apply,call,bind三者的区别

    摘要:一前言指向,,,的区别是一个经典的面试问题,同时在项目中会经常使用到的原生的方法。中可能会极大的避免了产生的错误,有时候需要维护老的项目还是有必要了解一下的指向和,,三者的区别。 一、前言 this指向,apply,call,bind的区别是一个经典的面试问题,同时在项目中会经常使用到的原生的js方法。同时也是ES5中的众多坑的一个。ES6中可能会极大的避免了this产生的错误,有时候...

    happen 评论0 收藏0
  • 一段人人都应该知道的从Vue到React的过渡史

    摘要:并根据官网文档的语法顺序,写了对应的的语法,并附一个教程。和受限元素一样,使用事件可以监听值的变化。有一个初始值,但这个值用户可以改变并会反应到界面上。 写在前面 以前写Vue写惯了,心血来潮,写起了react。并根据Vue官网文档的语法顺序,写了对应的React的语法,并附一个教程demo。 教程的github地址:Close2React 项目使用框架版本主要有 react(15.4...

    chadLi 评论0 收藏0
  • JS之函数(1)

    摘要:前言这段时间突然发现原生好多东西都忘记了但有些东西确实很重要所以又重新再梳理一次。 showImg(https://segmentfault.com/img/bVbqqkr?w=874&h=382); 前言 这段时间突然发现JS原生好多东西都忘记了,但有些东西确实很重要,所以又重新再梳理一次。主要有函数的3种定义方法,ES5函数this指向,call与appl用法,JS常见的4种设计模...

    宋华 评论0 收藏0
  • 我们不背诵 API,只实现 API

    摘要:接下来,我们换一种思路,用一个相对较新的来实现方法。从这道题目看出,相比考察死记硬背,这样的实现更有意义。对数组的操作我们不能陌生,其中方法更要做到驾轻就熟。最后,我们再看下社区上著名的和的实现。 有不少刚入行的同学跟我说:JavaScript 很多 API 记不清楚怎么办?数组的这方法、那方法总是傻傻分不清楚,该如何是好?操作 DOM 的方式今天记,明天忘,真让人奔溃! 甚至有的开发...

    wudengzan 评论0 收藏0

发表评论

0条评论

williamwen1986

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<