资讯专栏INFORMATION COLUMN

apply,call,bind的用法

HitenDev / 2886人阅读

摘要:在下例中的循环体内,我们创建了一个匿名函数,然后通过调用该函数的方法,将每个数组元素作为指定的执行了那个匿名函数。当然,这里不是必须得让数组元素作为值传入那个匿名函数,目的是为了演示的用法。

apply()

Function.prototype.apply()将会调用一个以this和数组形式的arguments为参数的方法。
m

fun.apply(thisArg,[argsArray])

每当要为一个新的对象添加一个方法时,有时不得不为其重写一个方法。而如果利用apply的话,只需要写一次方法,然后在这个新的对象中继承它即可,十分方便。
apply和call方法十分相似,仅仅只是参数不同而已,但正是因为这一点,我们在用apply时不必知道被调用的对象的具体参数,可以只穿arguments,如此一来,被调用的这个对象将负责handle触底的arguments。
1.我们可以像Java那样,利用apply为一个对象创建构造链。在下面的例子中,我们将创建一个名为construct的全局方法,这个方法可以不必让你传递一个一个的参数,取而代之的则是传递一个参数数组。当地一个参数为null时,指向的时window对象。

// Function.prototype.construct = function(aArgs) {
//   var oNew = Object.create(this.prototype);
//   this.apply(oNew, aArgs);
//   return oNew;
// };

//Function.prototype.construct = function(aArgs) {
//  var fConstructor = this, fNewConstr = function() { 
//    fConstructor.apply(this, aArgs); 
//  };
// fNewConstr.prototype = fConstructor.prototype;
//  return new fNewConstr();
//};

Function.prototype.construct = function (aArgs) {
  var fNewConstr = new Function("");
  fNewConstr.prototype = this.prototype;
  var oNew = new fNewConstr();
  this.apply(oNew, aArgs);
  return oNew;
};
function MyConstructor() {
  for (var nProp = 0; nProp < arguments.length; nProp++) {
    this["property" + nProp] = arguments[nProp];
  }
}
var myArray = [4, "Hello world!", false];
var myInstance = MyConstructor.construct(myArray);
console.log(myInstance.property1);                // logs "Hello world!"
console.log(myInstance instanceof MyConstructor); // logs "true"
console.log(myInstance.constructor);  
function minOfArray(arr){
    var min = Infinity;
    var QUANTUM = 32768;
    var len=arr.length;
    for(var i=0;i
    function Person(name,age)  
    {  
        this.name=name;  
        this.age=age;  
    }  
    /*定义一个学生类*/  
    function Student(name,age,grade)  
    {  
        Person.apply(this,arguments);  
        this.grade=grade;  
    }  
    //创建一个学生类  
    var student=new Student("zhangsan",21,"一年级");  
    //测试  
    alert("name:"+student.name+"
"+"age:"+student.age+"
"+"grade:"+student.grade);  
call()

call()方法调用一个函数,其具体有一个指定的this值和分别地提供的参数。
注意:

该方法的作用和apply()方法类似,只有一个区别,就是call()方法接受的是若干个参数的列表,而apply()方法接受的是一个包含多个参数的数组。

fun.call(thisArg,arg1,arg2,...)
参数:

在fun函数运行时指定的是this值。需要注意的是,指定的this值并不一定是该函数执行时真正的this值,如果这个函数处于非严格模式下,则指定为null和undefinde的this值会自动指向全局对象,同时值为原始值(数字,字符串,布尔值)的this会指向该原始值的自动包装对象。
arg1,arg2指定的参数列表。

返回值:

返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。

call()允许为不同的对象分配和调用属于一个对象的函数/方法。
可以让call()中的对象调用当前对象所拥有的function。你剋以使用call()来实现继承:写一个方法,然后让另一个新的对象来继承它。

function Product(name,price){
    this.name = name;
    this.price = price;
}
function Food(name,price){
    Product.call(this,name,price);
    this.category = "food"
}
console.log(new Food("cheese",5).name)//cheese
//在一个子勾走函数中,你可以通过调用父构造函数的call方法来实现继承,类似于Java中的写法。下例中,使用Food和Toy构造函数创建的对象示例都会拥有Product构造函数中添加的name属性和price属性,但category属性是在各自的构造函数中定义的。
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);

使用call方法调用匿名函数。
在下例中的for循环体内,我们创建了一个匿名函数,然后通过调用该函数的call方法,将每个数组元素作为指定的this执行了那个匿名函数。这个匿名函数的主要目的是给每个数组元素对象添加一个print方法,这个print方法可以打印出各元素在数组中的正确索引号。当然,这里不是必须得让数组元素作为this值传入那个匿名函数,目的是为了演示call的用法。

var animals = [
    {species:"Lion",name:"King"},
    {species:"Whale",name:"Fail"}
];
for(var i=0;i

使用call方法调用函数并且指定上下文的this
在下面的例子中,当调用greet方法的时候,该方法的this值会绑定到i对象。

function greet(){
    var reply = [this.person,"Is An Awesome",this.role].join("");
    console.log(reply);
}
var i = {
    person:"Douglas Crockford",
    role:"JavaScript DeveLoper"
}
greet.call(i);// Douglas Crockford Is An Awesome Javascript Developer
bind()

bind()方法创建一个新的函数,当这个新函数被调用时this键值为其提供的值,其参数列表前几项值为创建时指定的参数序列。
语法:

fun.bind(thisArg[,arg1[,arg2[,...]]])

参数:

thisArg调用绑定函数时作为this参数传递给目标函数的值。如果使用new运算符构造绑定函数,则忽略该值。当使用bind在setTimeout中创建一个函数(作为回调提供)时,作为thisArg传递的任何原始值都将转换为object。如果没有提供绑定的参数,则执行作用域的this被视为新函数的thisArg
arg1,arg2,...当绑定函数被调用时,这些参数将置于实参之前传递给被绑定的方法。

返回值:

返回由指定的this值和初始化参数改造的原函数拷贝。
    this.x = 9; 
    var module = {
        x: 81,
        getX: function() { return this.x; }
    };

    console.log(module.getX()); // 返回 81

    var retrieveX = module.getX.bind(module);
    console.log(retrieveX()); // 返回 9, 在这种情况下,"this"指向全局作用域

    // 创建一个新函数,将"this"绑定到module对象
    // 新手可能会被全局的x变量和module里的属性x所迷惑
    var boundGetX = retrieveX.bind(module);
    console.log(boundGetX()); // 返回 81
var o={
    f:function(){
        var self = this;
        var fff = function(){
            console.log(self.value)//此时this指向的是全局作用域,因此需要使用self指向对象o
        };
        fff();
    },
    value:"Hello World"
};
o.f()//Hello World!

上例子是我们常用了保持this上下文的方法,把this赋值给了中间变量self,这样在内部嵌套的函数中能够使用self访问到对象o,否则仍使用this.value,内部嵌套函数的this此时指向的是全局作用域,最后的输出将会是undefined。
但是,如果我们使用bind()函数,将fff函数的绑定在对象o中,即将fff()函数内部的this对象绑定为对象o,那么可以遇见此时this.value是存在的。代码如下:

var o={
    f:function(){
        var self = this;
        var fff = function(){
            console.log(this.value);
        }.bind(this);
        fff();
    }
    valeu:"Hello World!"
}
o.f()//Hello World!

更普通的使用情形:

function f(y,z){
    return this.x+y+z;
}
var m = f.bind({X;1},2);
console.log(m(3))

最后将输出6
这是因为bind()方法会把传入它的第一个实参绑定给f函数体的this,从第二个实参起,将依次传递给原始函数,因此{x:1}传递给this,2传递给形参y,m(3)调用时的3传递给形参z.

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

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

相关文章

  • bind()、call()、apply()理解及用法

    摘要:首先,我们判断是否存在方法,然后,若不存在,向对象的原型中添加自定义的方法。指向调用它的对象。总之三个的使用区别都是用来改变函数的对象的指向的第一个参数都是要指向的对象都可以利用后续参数传参是返回对应函数,便于稍后调用,是立即调用 apply和call都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向),Function对象的方法,每个函数都能调用; 使用a...

    hoohack 评论0 收藏0
  • JavaScript 中 callapplybind 用法和区别

    摘要:和类似,都是调用函数,并指定函数的值和参数,区别在于传入参数是通过参数列表的形式,传入参数是通过数组的形式方法与前两个不同,它创建一个新的函数,在调用新函数时,会调用原函数,并指定原函数的值和参数。执行的时候并没有调用函数。 简介 JavaScript 中有三个方法Function.prototype.call()、Function.prototype.apply()和Function...

    wind3110991 评论0 收藏0
  • 复习javascript中call,apply,bind用法

    摘要:绑定函数被调用时,也接受预设的参数提供给原函数。一个绑定函数也能使用操作符创建对象这种行为就像把原函数当成构造器。 一直很难理解js中的call apply bind,在w3schools,mdn阅读了,也看了很多相关的文章,今天我来写下我理解的call apply bind 首先创建一个函数 function man(){} man.prototype = { name: ...

    darryrzhong 评论0 收藏0
  • 关于javascript中bindcallapply等函数用法

    摘要:其实它们都很简单,但是在处理一些与相关的函数的时候,用来改变函数中的指向,却是必不可少的工具,所以必须掌握好它们的用法。 关于javascript中的bind、call、apply等函数的用法 我GitHub上的菜鸟仓库地址: 点击跳转查看其他相关文章 文章在我的博客上的地址: 点击跳转         前面的文章已经说到this的指向了,那么这篇文章就要说一说和this相关的三个...

    lordharrd 评论0 收藏0
  • JS中call(),apply()和bind()方法

    摘要:奔着一星期彻底弄清楚一个小知识点的目的这次的目标是方法在实际项目中经常会用到这三个函数只是简单的知道都是用来进行上下文绑定的这三个函数都可以实现现在看来这三者还是有很大区别的特别是和其他两个的区别先说和目的是改变函数的执行上下文下面列举一些 奔着一星期彻底弄清楚一个javascript小知识点的目的,这次的目标是call apply bind方法 在实际项目中,经常会用到这三个函数,只...

    nifhlheimr 评论0 收藏0
  • 「干货」细说 callapply 以及 bind 区别和用法

    摘要:的调用者,将会指向这个对象。此外,还可以扩展自己的其他方法。的使用最后来说说。不同的是,方法的返回值是函数,并且需要稍后调用,才会执行。而和则是立即调用。总结和的主要作用,是改变对象的执行上下文,并且是立即执行的。 前言 上一篇文章 《「前端面试题系列4」this 的原理以及用法》 中,提到了 call 和 apply。 它们最主要的作用,是改变 this 的指向。在平时的工作中,除了...

    GraphQuery 评论0 收藏0

发表评论

0条评论

HitenDev

|高级讲师

TA的文章

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