Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript调用();应用()与绑定()?_Javascript_Arrays_Function - Fatal编程技术网

Javascript调用();应用()与绑定()?

Javascript调用();应用()与绑定()?,javascript,arrays,function,Javascript,Arrays,Function,我已经知道apply和call是设置此(函数上下文)的类似函数 区别在于我们发送参数的方式(手动与数组) 问题: 但是什么时候应该使用bind()方法呢 var obj = { x: 81, getX: function() { return this.x; } }; alert(obj.getX.bind(obj)()); alert(obj.getX.call(obj)); alert(obj.getX.apply(obj)); 当您希望稍后使用特定上下文调用该函数时

我已经知道
apply
call
是设置
(函数上下文)的类似函数

区别在于我们发送参数的方式(手动与数组)

问题:

但是什么时候应该使用
bind()
方法呢

var obj = {
  x: 81,
  getX: function() {
    return this.x;
  }
};

alert(obj.getX.bind(obj)());
alert(obj.getX.call(obj));
alert(obj.getX.apply(obj));

当您希望稍后使用特定上下文调用该函数时,请使用
.bind()
,该函数在事件中非常有用。如果要立即调用函数,请使用
.call()
.apply()
,并修改上下文

Call/apply立即调用函数,而
bind
返回一个函数,该函数在以后执行时,将为调用原始函数设置正确的上下文。通过这种方式,您可以在异步回调和事件中维护上下文

我经常这样做:

function MyObject(element) {
    this.elm = element;

    element.addEventListener('click', this.onClick.bind(this), false);
};

MyObject.prototype.onClick = function(e) {
     var t=this;  //do something with [t]...
    //without bind the context of this function wouldn't be a MyObject
    //instance as you would normally expect.
};
我在Node.js中广泛使用它进行异步回调,我希望为其传递成员方法,但仍然希望上下文是启动异步操作的实例

bind的简单、朴素的实现如下:

Function.prototype.bind = function(ctx) {
    var fn = this;
    return function() {
        fn.apply(ctx, arguments);
    };
};
还有更多内容(比如传递其他参数),但是您可以阅读更多关于它的内容,并了解真正的实现


希望这有帮助。

它允许设置该函数的值,而不依赖于函数的调用方式。这在处理回调时非常有用:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(sayHello.bind(obj), 1000);
要使用
调用
获得相同的结果,如下所示:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"
...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"

TL;医生:

简单地说,bind创建函数,call和apply执行函数,而apply需要数组中的参数

完整解释

假设我们有
乘法
函数

function multiplication(a,b){
console.log(a*b);
}
// So we are passing null because we are not using the "this" keyword in our greet function.
var greetAnAdultMale = greet.bind (null, "male", 45);

greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."

var greetAYoungster = greet.bind (null, "", 16);
greetAYoungster ("Alex"); // "Hey, Alex."​
greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
让我们使用
bind

var multiby2=multiply.bind(这个,2)

现在乘法2(b)等于乘法(2,b)

如果我在bind中传递这两个参数呢

var getSixAlways = multiplication.bind(this,3,2);
现在getSixAlways()等于乘法(3,2)

即使传递参数也返回6;
getSixAlways(12)//6

var magicMultiplication = multiplication.bind(this);
这将创建一个新的乘法函数并将其分配给magicMultiplication

哦,不,我们将乘法功能隐藏在magicMultiplication中

召唤
magicMultiplication
返回一个空白的
函数b()

在执行过程中效果很好
magicMultiplication(6,5)//30

打电话申请怎么样

magicMultiplication.call(this,3,2)//6

var magicMultiplication = multiplication.bind(this);
magicMultiplication.apply(这个[5,2])//10

它们都将此附加到函数(或对象)中,区别在于函数调用(见下文)

调用将此附加到函数中,并立即执行该函数:

var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
person.hello.call({ name: "Jim Smith" }, "world"); // output: "Jim Smith says hello world"
func.call(context, arguments);
func.apply(context, [argument1,argument2,..]);
bind这个附加到函数中,需要像这样单独调用它:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"
...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"
或者像这样:

  function sayHello(){
    alert(this.message);
  }

  var obj = {
     message : "hello"
  };
  setTimeout(function(){sayHello.call(obj)}, 1000);
var person = {  
  name: "James Smith",
  hello: function(thing) {
    console.log(this.name + " says hello " + thing);
  }
}

person.hello("world");  // output: "James Smith says hello world"
var helloFunc = person.hello.bind({ name: "Jim Smith" });
helloFunc("world");  // output: Jim Smith says hello world"
...    
var helloFunc = person.hello.bind({ name: "Jim Smith" }, "world");
helloFunc();  // output: Jim Smith says hello world"
applycall类似,不同之处在于它采用类似数组的对象,而不是一次列出一个参数:

function personContainer() {
  var person = {  
     name: "James Smith",
     hello: function() {
       console.log(this.name + " says hello " + arguments[1]);
     }
  }
  person.hello.apply(person, arguments);
}
personContainer("world", "mars"); // output: "James Smith says hello mars", note: arguments[0] = "world" , arguments[1] = "mars"                                     
使用给定的
此值调用函数,并返回该函数的返回值

// Define an object with some properties and a method​
// We will later pass the method as a callback function to another function​
var clientData = {
    id: 094545,
    fullName: "Not Set",
    // setUserName is a method on the clientData object​
    setUserName: function (firstName, lastName)  {
        // this refers to the fullName property in this object​
        this.fullName = firstName + " " + lastName;
    }
};

function getUserInput (firstName, lastName, callback, callbackObj) {
     // The use of the Apply method below will set the "this" value to callbackObj​
     callback.apply (callbackObj, [firstName, lastName]);
}

// The clientData object will be used by the Apply method to set the "this" value​
getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
// the fullName property on the clientData was correctly set​
console.log (clientData.fullName); // Barack Obama
另一方面,使用给定的
this
值创建一个新函数,并返回该函数而不执行它

所以,让我们来看看这样的函数:

var logProp = function(prop) {
    console.log(this[prop]);
};
var Obj = {
    x : 5,
    y : 10
};
Obj.log = logProp.bind(Obj);
现在,让我们看一个像这样的对象:

var logProp = function(prop) {
    console.log(this[prop]);
};
var Obj = {
    x : 5,
    y : 10
};
Obj.log = logProp.bind(Obj);
我们可以像这样将函数绑定到对象:

var logProp = function(prop) {
    console.log(this[prop]);
};
var Obj = {
    x : 5,
    y : 10
};
Obj.log = logProp.bind(Obj);
现在,我们可以在代码中的任何位置运行
Obj.log

Obj.log('x'); // Output : 5
Obj.log('y'); // Output : 10

真正有趣的是,您不仅为
this
绑定了一个值,还为其参数
prop
绑定了一个值:

Obj.logX = logProp.bind(Obj, 'x');
Obj.logY = logProp.bind(Obj, 'y');
我们现在可以这样做:

Obj.logX(); // Output : 5
Obj.logY(); // Output : 10
这里有一个例子来说明
bind()
apply()
call()
之间的区别,总结如下

  • bind()
    允许我们轻松设置调用函数或方法时将哪个特定对象绑定到此对象

    // This data variable is a global variable​
    var data = [
        {name:"Samantha", age:12},
        {name:"Alexis", age:14}
    ]
    var user = {
        // local data variable​
        data    :[
            {name:"T. Woods", age:37},
            {name:"P. Mickelson", age:43}
        ],
        showData:function (event) {
            var randomNum = ((Math.random () * 2 | 0) + 1) - 1; // random number between 0 and 1​
            console.log (this.data[randomNum].name + " " + this.data[randomNum].age);
        }
    }
    
    // Assign the showData method of the user object to a variable​
    var showDataVar = user.showData;
    showDataVar (); // Samantha 12 (from the global data array, not from the local data array)​
    /*
    This happens because showDataVar () is executed as a global function and use of this inside 
    showDataVar () is bound to the global scope, which is the window object in browsers.
    */
    
    // Bind the showData method to the user object​
    var showDataVar = user.showData.bind (user);
    // Now the we get the value from the user object because the this keyword is bound to the user object​
    showDataVar (); // P. Mickelson 43​
    
  • bind()
    允许我们借用方法

    // Here we have a cars object that does not have a method to print its data to the console​
    var cars = {
        data:[
           {name:"Honda Accord", age:14},
           {name:"Tesla Model S", age:2}
       ]
    }
    
    // We can borrow the showData () method from the user object we defined in the last example.​
    // Here we bind the user.showData method to the cars object we just created.​
    cars.showData = user.showData.bind (cars);
    cars.showData (); // Honda Accord 14​
    
    这个例子的一个问题是,我们在
    cars
    对象上添加了一个新方法
    showData
    ,并且 我们可能不想这样做只是为了借用一个方法,因为cars对象可能已经有了一个属性或方法名
    showData
    。 我们不想意外地覆盖它。正如我们将在下面的
    应用
    调用
    讨论中看到的那样, 最好借用使用
    Apply
    Call
    方法的方法

  • bind()
    允许我们使用函数

    ,也称为部分函数应用程序,是使用 函数(接受一个或多个参数),该函数返回一个已设置某些参数的新函数

    function greet (gender, age, name) {
        // if a male, use Mr., else use Ms.​
        var salutation = gender === "male" ? "Mr. " : "Ms. ";
        if (age > 25) {
            return "Hello, " + salutation + name + ".";
        }else {
            return "Hey, " + name + ".";
        }
     }
    
    我们可以使用
    bind()
    来实现这个
    greet
    函数

    function multiplication(a,b){
    console.log(a*b);
    }
    
    // So we are passing null because we are not using the "this" keyword in our greet function.
    var greetAnAdultMale = greet.bind (null, "male", 45);
    
    greetAnAdultMale ("John Hartlove"); // "Hello, Mr. John Hartlove."
    
    var greetAYoungster = greet.bind (null, "", 16);
    greetAYoungster ("Alex"); // "Hey, Alex."​
    greetAYoungster ("Emma Waterloo"); // "Hey, Emma Waterloo."
    
  • apply()
    call()
    设置此值

    apply
    call
    bind
    方法都用于在调用方法时设置this值,它们只需稍加修改即可 允许在JavaScript代码中使用直接控制和多功能性的不同方法

    设置此值时,
    apply
    call
    方法几乎相同,只是将函数参数作为数组传递给
    apply()
    ,而必须单独列出参数才能将其传递给
    call()
    方法

    下面是一个使用
    call
    apply
    在回调函数中进行设置的示例

    // Define an object with some properties and a method​
    // We will later pass the method as a callback function to another function​
    var clientData = {
        id: 094545,
        fullName: "Not Set",
        // setUserName is a method on the clientData object​
        setUserName: function (firstName, lastName)  {
            // this refers to the fullName property in this object​
            this.fullName = firstName + " " + lastName;
        }
    };
    
    function getUserInput (firstName, lastName, callback, callbackObj) {
         // The use of the Apply method below will set the "this" value to callbackObj​
         callback.apply (callbackObj, [firstName, lastName]);
    }
    
    // The clientData object will be used by the Apply method to set the "this" value​
    getUserInput ("Barack", "Obama", clientData.setUserName, clientData);
    // the fullName property on the clientData was correctly set​
    console.log (clientData.fullName); // Barack Obama
    
  • 使用
    应用
    调用

    • 借用数组方法

      让我们创建一个类似于
对象的
数组,并借用一些数组方法来操作我们的数组
var person1 = {firstName: 'Jon', lastName: 'Kuperman'};
var person2 = {firstName: 'Kelly', lastName: 'King'};

function say() {
    console.log('Hello ' + this.firstName + ' ' + this.lastName);
}

var sayHelloJon = say.bind(person1);
var sayHelloKelly = say.bind(person2);

sayHelloJon(); // Hello Jon Kuperman
sayHelloKelly(); // Hello Kelly King
    function sayHello() {
            //alert(this.message);
            return this.message;
    }
    var obj = {
            message: "Hello"
    };

    function x(country) {
            var z = sayHello.bind(obj);
            setTimeout(y = function(w) {
//'this' reference not lost
                    return z() + ' ' + country + ' ' + w;
            }, 1000);
            return y;
    }
    var t = x('India')('World');
    document.getElementById("demo").innerHTML = t;
var car = { 
  registrationNumber: "007",
  brand: "Mercedes",

  displayDetails: function(ownerName){
    console.log(ownerName + ' this is your car ' + '' + this.registrationNumber + " " + this.brand);
  }
}
car.displayDetails('Nishant'); // **Nishant this is your car 007 Mercedes**
var car1 = car.displayDetails('Nishant');
car1(); // undefined
var car1 = car.displayDetails.bind(car, 'Nishant');
car1(); // Nishant this is your car 007 Mercedes
var func = function() {
 console.log(this)
}.bind(1);

func();
// Number: 1
var func = function() {
 console.log(this)
}.bind({});

func();
// Object
var Name = { 
    work: "SSE",
    age: "25"
}

function displayDetails(ownerName) {
    console.log(ownerName + ", this is your name: " + 'age' + this.age + " " + 'work' + this.work);
}
displayDetails.call(Name, 'Nishant')
// Nishant, this is your name: age25 workSSE

// In apply we pass an array of arguments
displayDetails.apply(Name, ['Nishant'])
// Nishant, this is your name: age25 workSSE
var obj = {name: "Raushan"};

var greeting = function(a,b,c) {
    return "Welcome "+ this.name + " to "+ a + " " + b + " in " + c;
};

console.log(greeting.call(obj, "USA", "INDIA", "ASIA"));
var obj = {name: "Raushan"};

var cal = function(a,b,c) {
    return this.name +" you got " + a+b+c;
};

var arr =[1,2,3];  // array format for function arguments
console.log(cal.apply(obj, arr)); 
       var obj = {name: "Raushan"};

       var cal = function(a,b,c) {
            return this.name +" you got " + a+b+c;
       };

       var calc = cal.bind(obj);
       console.log(calc(2,3,4));
const person = {
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.call(anotherPerson,1,2)
    name: "Lokamn",
    dob: 12,
    print: function (value,value2) {
        console.log(this.dob+value+value2)
    }
}
const anotherPerson= {
     name: "Pappu",
     dob: 12,
}
 person.print.apply(anotherPerson,[1,2])
    name: "Lokamn",
    dob: 12,
    anotherPerson: {
        name: "Pappu",
        dob: 12,
        print2: function () {
            console.log(this)
        }
    }
}

var bindFunction = person.anotherPerson.print2.bind(person)
 bindFunction()
let name =  {
    firstname : "Arham",
    lastname : "Chowdhury",
}
printFullName =  function(hometown,company){
    console.log(this.firstname + " " + this.lastname +", " + hometown + ", " + company)
}
printFullName.call(name,"Mumbai","Taufa");     //Arham Chowdhury, Mumbai, Taufa
printFullName.apply(name, ["Mumbai","Taufa"]);     //Arham Chowdhury, Mumbai, Taufa
let printMyNAme = printFullName.bind(name,"Mumbai","Taufa");

printMyNAme();      //Arham Chowdhury, Mumbai, Taufa