简体   繁体   English

javascript调用函数里面的另一个谜

[英]javascript calling function inside another mystery

function Obj1(param) { this.test1 = param || 函数Obj1(param){this.test1 = param || 1; 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? 输出是55? how can 'view' test1 an Obj2 istance if I haven't link both via prototype chain? 如果我没有通过原型链链接,怎么能'查看'test1是一个Obj2 istance?

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: 您将Obj1方法添加到Obj2的对象实例,并在此处使用它:

this.ob(par); 

the context of "this" inside the method Obj1 is the Obj2 instance . 方法Obj1中的“this”的上下文是Obj2实例 So that instance now has a test1 member. 所以该实例现在有一个test1成员。

Nothing to do with inheritance really, but it's a bit like a mix-in. 与继承无关,但它有点像混合。 Remember in JS functions are first class objects. 记住在JS函数中是第一类对象。

Let think about Obj1 as a function . 让我们将Obj1视为一种功能 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? 如果我没有通过原型链链接,怎么能'查看'test1是一个Obj2 istance?

Methods are not bound in JavaScript. 方法不受JavaScript限制。 When you write one of: 当你写下一个:

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

the value of 'o' is assigned to 'this' inside the method. 'o'的值在方法内分配给'this'。 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'. 对'o'的引用丢失了,并且该方法被称为好像是一个普通的旧函数,全局对象为'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'将是'o2',而不是'o'。 This is extremely strange behaviour for a language with first-class functions, and highly counter-intuitive, but that's JavaScript for you. 对于具有一流功能的语言而言,这是非常奇怪的行为,而且非常反直觉,但这是适合您的JavaScript。

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. 请参阅ECMAScript 3.1提出的“Function.bind”方法或许多框架中的类似实现。

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. 这是将Obj1作为一个函数并转换为'this'的方法,这是一个Obj2实例。 So when Obj1 is called, its own 'this' is also an Obj2, and that's the 'this' it writes its param to. 因此,当Obj1被调用时,它自己的'this'也是一个Obj2,那就是'this'它写它的参数。 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. 它可以用作一种继承,在你自己的类上调用另一个类的构造函数,这个方法在一些JS面向对象的教程中讲授。 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. 什么this函数内部指的是取决于你如何调用该函数。 If you call it as sender.fn() , then this is sender (your case). 如果你把它称为sender.fn() ,那么this就是sender (你的情况)。 If you do it as fn() , then this is the global object. 如果你这样做fn() ,那么this就是全局对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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