资讯专栏INFORMATION COLUMN

根据一道题引发的call、apply、bind方法总结

ormsf / 3260人阅读

摘要:首先介绍一下和的定义和的作用是改变函数运行时的上下文环境改变的指向将绑定到或者说调用了里面的方法。方法返回的是修改过后的函数追梦子追梦子执行成功

这是一道今天遇到的面试题

因为setTimeout属于匿名函数,this指向window,所以this.id = 1
但还是先总结一下call和apply的用法。

首先介绍一下call和apply的定义

obj.call(thisObj, arg1, arg2,...)
obj.apply(thisObj, [arg1, arg2,...])

call和apply的作用是改变函数运行时的上下文环境(改变this的指向),将obj绑定到thisObj,或者说this.Obj调用了obj里面的方法。

call和apply的作用

当一个对象需要调用另外一个对象里面的方法的时候,可以用到call和apply,call和apply可以理解成是继承另外一个对象的方法。

首先我们建立两个对象obj1和obj2

如果obj2对象要调用obj1中的func1方法(可以理解为在obj2的环境中执行obj1.func1方法),则

 obj1.func1.call(obj2); //输出:obj2Name
 obj1.func1.apply(obj2);//输出:obj2Name

call和apply第一个参数都是表示obj1绑定的对象,如果obj1要绑定到this,此时obj1就是绑定到全局,如:

 obj1.func1.call(this);//输出:windowName
 obj1.func1.apply(this);//输出:windowName

如果obj2对象要调用obj1中的func2方法,则

  obj1.func2.call(obj2,1,2);//输出:3
  obj1.func2.apply(obj2,[1,2]);//输出:3
call和apply实现继承

使用call方法调用父构造函数

function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError(
      "Cannot create product " + this.name + " with a negative price"
    );
  }
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = "food";
}

//等同于
function Food(name, price) {
  this.name = name;
  this.price = price;
  if (price < 0) {
    throw RangeError(
      "Cannot create product " + this.name + " with a negative price"
    );
  }

  this.category = "food";
}

//function Toy 同上
function Toy(name, price) {
  Product.call(this, name, price);
  this.category = "toy";
}

var cheese = new Food("feta", 5);
var fun = new Toy("robot", 40);
bind方法和call、apply的区别

bind方法也是用来改变this的指向

var a = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);
    }
}
var b = a.fn;
b.bind(a);

没有被打印,这就是bind方法与apply、call方法的不同。bind方法返回的是修改过后的函数

var a = {
    user:"追梦子",
    fn:function(){
        console.log(this.user); //追梦子
    }
}
var b = a.fn;
var c = b.bind(a);
c();

执行成功

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

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

相关文章

  • 一道面试,到“我可能看了假源码”

    摘要:返回的绑定函数也能使用操作符创建对象这种行为就像把原函数当成构造器。同时,将第一个参数以外的其他参数,作为提供给原函数的预设参数,这也是基本的颗粒化基础。 今天想谈谈一道前端面试题,我做面试官的时候经常喜欢用它来考察面试者的基础是否扎实,以及逻辑、思维能力和临场表现,题目是:模拟实现ES5中原生bind函数。也许这道题目已经不再新鲜,部分读者也会有思路来解答。社区上关于原生bind的研...

    Carson 评论0 收藏0
  • 一道面试,到“我可能看了假源码”

    摘要:返回的绑定函数也能使用操作符创建对象这种行为就像把原函数当成构造器。同时,将第一个参数以外的其他参数,作为提供给原函数的预设参数,这也是基本的颗粒化基础。 今天想谈谈一道前端面试题,我做面试官的时候经常喜欢用它来考察面试者的基础是否扎实,以及逻辑、思维能力和临场表现,题目是:模拟实现ES5中原生bind函数。也许这道题目已经不再新鲜,部分读者也会有思路来解答。社区上关于原生bind的研...

    rockswang 评论0 收藏0
  • 一道面试,到“我可能看了假源码”

    摘要:返回的绑定函数也能使用操作符创建对象这种行为就像把原函数当成构造器。同时,将第一个参数以外的其他参数,作为提供给原函数的预设参数,这也是基本的颗粒化基础。 今天想谈谈一道前端面试题,我做面试官的时候经常喜欢用它来考察面试者的基础是否扎实,以及逻辑、思维能力和临场表现,题目是:模拟实现ES5中原生bind函数。也许这道题目已经不再新鲜,部分读者也会有思路来解答。社区上关于原生bind的研...

    jlanglang 评论0 收藏0
  • 一道面试,到“我可能看了假源码[2]

    摘要:函数是这样子声明的使用了系统自己的构造函数来声明,第一个参数是,函数体内又。构造函数调用情况正常方式调用无穷无尽当然,里还归纳了几项比较简单,我就不再翻译了。 上一篇从一道面试题,到我可能看了假源码中,由浅入深介绍了关于一篇经典面试题的解法。最后在皆大欢喜的结尾中,突生变化,悬念又起。这一篇,就是为了解开这个悬念。 如果你还没有看过前传,可以参看前情回顾: 回顾1. 题目是模拟实现ES...

    chanthuang 评论0 收藏0
  • 可能遇到假面试:不用callapply方法模拟实现ES5bind方法

    摘要:来自朋友去某信用卡管家的做的一道面试题,用原生模拟的方法,不准用和方法。他们的用途相同,都是在特定的作用域中调用函数。不同之处在于,方法传递给调用函数的参数是逐个列出的,而则是要写在数组中。 本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?。 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法。 ...

    李世赞 评论0 收藏0

发表评论

0条评论

ormsf

|高级讲师

TA的文章

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