简体   繁体   中英

javascript calling function inside another mystery

function Obj1(param) { this.test1 = param || 1; }

function Obj2(param, par)
{
    this.test2 = param;
    this.ob = Obj1;
    this.ob(par);
}

now why if I do:

alert(new Obj2(44,55).test1); 

the output is 55? how can 'view' test1 an Obj2 istance if I haven't link both via prototype chain?

Thanks

Well it's not clear what you want but the reason this happens is because here:

this.ob = Obj1;

you add the Obj1 method to the object instance of Obj2, and when you use it here:

this.ob(par); 

the context of "this" inside the method Obj1 is the Obj2 instance . So that instance now has a test1 member.

Nothing to do with inheritance really, but it's a bit like a mix-in. Remember in JS functions are first class objects.

Let think about Obj1 as a function . So, when you do

function Obj2(param, par)
{
    this.test2 = param;
    this.ob = Obj1;
    this.ob(par);
}

your code become identical to the following code:

function Obj2(param, par)
{
    this.test2 = param;
    this.ob = function (param) { this.test1 = param || 1; }
    this.ob(par);
}

how can 'view' test1 an Obj2 istance if I haven't link both via prototype chain?

Methods are not bound in JavaScript. When you write one of:

o.method(x);
o['method'](x);

the value of 'o' is assigned to 'this' inside the method. But! If you detach the function from its object and call it directly:

m= o.method;
m(x);

the reference to 'o' is lost, and the method is called as if it were a plain old function, with the global object as 'this'. Similary, if you move the function to another object and call it there:

o2.method= o.method;
o2.method(x);

then 'this' will be 'o2', and not 'o'. This is extremely strange behaviour for a language with first-class functions, and highly counter-intuitive, but that's JavaScript for you.

If you want to be able to use bound methods, you'll need to create your own, generally using a closure. See ECMAScript 3.1's proposed "Function.bind" method or the similar implementation in many frameworks.

So anyway:

this.ob = Obj1;
this.ob(par);

This is taking Obj1 as a function and turning into a method on 'this', which is an Obj2 instance. So when Obj1 is called, its own 'this' is also an Obj2, and that's the 'this' it writes its param to. The same could be written more simply and clearly as:

Obj1.call(this, par);

Are you doing this deliberately? It can be used as a kind of inheritance, to call another class's constructor on your own class, and this method is taught in some JS object-orientation tutorials. However it really isn't a very good way of doing it because you end up with multiple copies of the same property; using prototypes would save you this, and make a property update on a superclass filter through to the subclasses as expected.

What this inside a function refers to depends on how you call the function. If you call it as sender.fn() , then this is sender (your case). If you do it as fn() , then this is the global object.

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