Javascript一天学完系列(四)函数上下文bind &call

Function Context函数下文bind &call


Functions in JavaScript run in a specific context, and using the this variable we have access to it.

浏览器中的所有标准功能都在Window上下文下运行。 在对象或类下定义的函数(另一个函数)将使用在其内创建对象的上下文。但是,我们也可以在运行时(在执行函数之前或同时)更改函数的上下文。

Binding a method to an object

To bind a function to an object and make it an object method, we can use the bind function. Here is a simple example:

var person = {
    name : "John"
};

function printName()
{
    console.log(this.name);
}

Obviously, we are not able to call printName() without associating the function with the object person. To do this we must create a bound method of the function printName to person, using the following code:

var boundPrintName = printName.bind(person);
boundPrintName();    // prints out "John"

Calling a function with a different context

我们可以使用call和apply函数来调用函数,就像它绑定到对象一样。 调用函数和Apply函数之间的区别仅在于它们如何接收其参数-调用函数首先接收this参数,然后接收函数的参数,而apply函数首先接收this参数,并接收参数数组 传递给函数,作为函数的第二个参数。

For example, let's call printName with person as the context using the call method:

printName.call(person);      // prints out "John"

call/apply vs bind

call/apply and bind之间的区别在于,绑定返回的新函数与旧函数相同,只是新函数中的this值现在是绑定到的对象。 call / apply将此函数作为绑定对象来调用该函数,但是它不会返回return新函数或更改原始函数,而是使用不同的值来调用它。

For example:

var boundPrintName = printName.call(person);    //boundPrintName gets printName's return value (null)
boundPrintName();                               //doesn't work because it's not a function, it's null

printName.bind(person);                         //returns a new function, but nothing is using it so it's useless
printName();                                    //throws error because this.name is not defined

Think of call as executing the return value of bind.

For example:

printName.call(person);     //is the same as
printName.bind(person)();   //executes the function returned by bind

Or think of bind returning a shortcut to call.

For example:

var boundPrintName = printName.bind(person); //is the same as
var boundPrintName = function()
{
    printName.call(person);
}

Exercise

Create bound copies of printFullName and printDetails to person called boundPrintFullName and boundPrintDetails.

Answer

var person = {
    firstName : "John",
    lastName : "Smith",
    age : 23
};

function printFullName()
{
    console.log(this.firstName + " " + this.lastName);
}

function printDetails()
{
    console.log(this.firstName + " is " + this.age + " years old");
}

// TODO: create bound copies of printFullName and printDetails.
var boundPrintFullName=printFullName.bind(person);
var boundPrintDetails=printDetails.bind(person);

boundPrintFullName();
boundPrintDetails();

var person={
    name:"yanhao",
    age:"20",
    
}
function printName()
{
    console.log(this.name);
}
function printAge()
{
    console.log(this.age);
}
//111111
var a=printName.bind(person);
a();
var b=printAge.bind(person);
b();
//222
printName.bind(person)();
printAge.bind(person)();
//333
printName.call(person); 
printAge.call(person);


> "yanhao"
> "20"
> "yanhao"
> "20"
> "yanhao"
> "20"

总结理解:bind会返回一个新的函数 接不接受是你的事情 不接受的话可以在后面加括号来调用(情况2) 接受的话用个var来接受,后面可以通过这个var来调用(情况1)

​ call就像一次性的东西一样(情况3)

posted @ 2020-02-20 14:29  Yan_Hao  阅读(172)  评论(0编辑  收藏  举报