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

时间:2022-04-03 23:57:42

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

函数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?

输出是55?如果我没有通过原型链链接,怎么能“查看”test1的Obj2 istance?

Thanks

4 个解决方案

#1


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. When you write one of:

方法不受JavaScript限制。当你写下一个:

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:

'o'的值在方法内分配给'this'。但!如果从该对象中分离该函数并直接调用它:

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:

对'o'的引用将丢失,并且该方法被称为就像它是一个普通的旧函数一样,全局对象为'this'。类似的,如果你将函数移动到另一个对象并在那里调用它:

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.

然后'this'将是'o2',而不是'o'。对于具有一流功能的语言而言,这是非常奇怪的行为,而且非常反直觉,但这是适合您的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. 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作为一个函数并转换为'this'的方法,这是一个Obj2实例。因此,当Obj1被调用时,它自己的'this'也是一个Obj2,那就是'this'它将它的param写入。同样可以写得更简单明了:

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.

你是故意这样做的吗?它可以用作一种继承,在你自己的类上调用另一个类的构造函数,这个方法在一些JS面向对象的教程中讲授。然而,它真的不是一个非常好的方法,因为你最终得到了相同属性的多个副本;使用原型可以节省您的时间,并在超类过滤器上进行属性更新,直到预期的子类。

#2


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. So that instance now has a test1 member.

方法Obj1中的“this”的上下文是Obj2实例。所以该实例现在有一个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函数是第一类对象。

#3


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

让我们将Obj1视为一种功能。所以,当你这样做的时候

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);
}

#4


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.

函数内部的含义取决于您调用函数的方式。如果你把它称为sender.fn(),那么这就是发送者(你的情况)。如果你这样做fn(),那么这就是全局对象。

#1


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. When you write one of:

方法不受JavaScript限制。当你写下一个:

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:

'o'的值在方法内分配给'this'。但!如果从该对象中分离该函数并直接调用它:

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:

对'o'的引用将丢失,并且该方法被称为就像它是一个普通的旧函数一样,全局对象为'this'。类似的,如果你将函数移动到另一个对象并在那里调用它:

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.

然后'this'将是'o2',而不是'o'。对于具有一流功能的语言而言,这是非常奇怪的行为,而且非常反直觉,但这是适合您的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. 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作为一个函数并转换为'this'的方法,这是一个Obj2实例。因此,当Obj1被调用时,它自己的'this'也是一个Obj2,那就是'this'它将它的param写入。同样可以写得更简单明了:

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.

你是故意这样做的吗?它可以用作一种继承,在你自己的类上调用另一个类的构造函数,这个方法在一些JS面向对象的教程中讲授。然而,它真的不是一个非常好的方法,因为你最终得到了相同属性的多个副本;使用原型可以节省您的时间,并在超类过滤器上进行属性更新,直到预期的子类。

#2


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. So that instance now has a test1 member.

方法Obj1中的“this”的上下文是Obj2实例。所以该实例现在有一个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函数是第一类对象。

#3


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

让我们将Obj1视为一种功能。所以,当你这样做的时候

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);
}

#4


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.

函数内部的含义取决于您调用函数的方式。如果你把它称为sender.fn(),那么这就是发送者(你的情况)。如果你这样做fn(),那么这就是全局对象。