简体   繁体   中英

how do you pass an instance function to an outside function?

let's say I have I have the following in a file called file1.js:

//constructor
function Blah(){

    this.string = "hello there agent ";

}

//'method'
Blah.prototype.greeting = function(num){
    return  this.string + num;
}

Then in a file called file2.js I then have this:

function combine(num,funct){
    return funct(num);
}

And then finally, in an html file called file3, I have this:

var bond = new Blah();
document.write(combine(007,bond.greeting));

I am actually getting into the "greeting" method, but for some reason, the return value, instead of being a string, winds up not being NaN. Any idea why? the greeting() method seems to be ran at the proper time. However, despite that, 007 seems to be getting interpreted as NaN anyway. Again, any suggestions as to what could be causing this?

Thanks a bunch in advance

First, depending on how you call the greeting method, the this value will be different. If you call it like bond.greeting(num) then this will be bond . If you call it like funct(num) , where funct is bond.greeting , then this will be the global object. You need to bind this permanently when passing the function along, to maintain its value no matter how you call the function.

Second, 007 === 7 . If you want to print out 007 literally, then you should use a string:

combine('007', bond.greeting.bind(bond));

Remember, this depends on how the function gets called, it is dynamic, and resolved an runtime, unless you bind it previously, like we did above.

You're experiencing the special characteristics of the this keyword.

Basically, this resolves to whatever you call a function from. In your case, you're calling it from the global scope from through func() , which makes this == window . (Calling it through bond.greeting() makes this == bond .)

To resolve, this either bind the function or force the resolution:

// note that this method requires a shim for IE 8 and older
document.write(combine(007,bond.greeting.bind(bond)));

or

function combine(num, obj, funct){
    // since funct is being called from obj, `this` == obj within the function
    return obj[funct](num);
}

document.write(combine(007,bond, 'greeting'));    

1) NaN is "Not a number" error. Try encapsulating 007 in quotes 2) Do you need file2.js or could you do without it?

var bond = new Blah();
document.write(bond.greeting("007"));

The problem you have is when you pass the function as argument, it is passed by value, and then you loose the reference to the object who has the element string = "hello there agent "; and when the function is executed, it executes "this.string" which doesn't exist inside the function, it returns undefined . It's a scope issue.

The solution to make it work good, is to pass the reference which is the object bond

function combine(num,obj){
    return obj.greeting(num);
}

combine("007",bond); // returns "hello there agent 007"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM