在Javascript ES6类中调用方法时出现意外行为

在Javascript ES6类中调用方法时出现意外行为,javascript,class,ecmascript-6,Javascript,Class,Ecmascript 6,我主要是一名C#开发人员,最近学习Javascript。我在试ES6课程。我希望ES6类的行为与常规类类似,但发现了许多异常 class Test{ constructor(){ console.log("Constructor Invoked"); } instanceMethod1(){ console.log("instanceMethod1 Invoked"); } instanceMethod2InvokesI

我主要是一名C#开发人员,最近学习Javascript。我在试ES6课程。我希望ES6类的行为与常规类类似,但发现了许多异常

class Test{
    constructor(){
        console.log("Constructor Invoked");
    }

    instanceMethod1(){
        console.log("instanceMethod1 Invoked");
    }

    instanceMethod2InvokesInstanceMethod1(){
        console.log("instanceMethod2InvokesInstanceMethod1 Invoked");
        this.instanceMethod1();
        //instanceMethod1(); //wont work in JS, but will work in C#
    }

    instanceMethod3InvokesStaticMethod1(){
        console.log("instanceMethod3InvokesStaticMethod1 Invoked");
        Test.staticMethod1();         
        //staticMethod1(); //Wont work in JS, but will work in C#
    }

    static staticMethod1(){
        console.log("staticMethod1 Invoked");
    }

    static staticMethod2InvokingStaticMethod1(){
        console.log("staticMethod2InvokingStaticMethod1 Invoked");
        this.staticMethod1();
        Test.staticMethod1();
        //staticMethod1(); //Wont work in JS, but will work in C#
    }

    static staticMethod3InvokingInstanceMethod1(){
        console.log("staticMethod3InvokingInstanceMethod1 Invoked");
        new Test().instanceMethod1();  
        //this.instanceMethod1(); //wont work 
    }
}

var ob = new Test();
ob.instanceMethod1();
ob.instanceMethod2InvokesInstanceMethod1();
ob.instanceMethod3InvokesStaticMethod1();

Test.staticMethod1(); 
Test.staticMethod2InvokingStaticMethod1();
Test.staticMethod3InvokingInstanceMethod1();
我的问题是:

  • instancemethod2调用instanceMethod1
    内部-为什么调用
    instanceMethod1()
    无效?没有实例就不能调用实例方法,因此在实例方法中调用实例方法应该有意义,对吗
  • 内部
    instanceMethod3调用staticMethod1
    -
    Test.staticMethod1()
    将正常工作。但是为什么我们不能直接调用
    staticMethod1
  • 内部
    staticmethod2调用staticMethod1
    -这个.staticMethod1()如何工作?这里的
    对象是什么
  • 在静态方法中,
    this.staticMethod1()
    可以工作,但不能
    this.instanceMethod1()
    。为什么?我想问题3的答案应该有助于回答这个问题

  • 有人能帮助我吗?

    你的第一个问题是假设JavaScript的行为像C++。有一些相似之处,但也有很多不同之处。您不应该立即期望在C++中工作的东西将在JavaScript中运行。它们不是同一种语言,这是C++开发者开始学习JavaScript时的常见问题(也发生在我身上)。 内部InstanceMethod2调用instanceMethod1-为什么调用instanceMethod1()不起作用?没有实例就不能调用实例方法,因此在实例方法中调用实例方法应该有意义,对吗

    不是C++,也没有提供这个特性。调用方法时必须使用对象前缀,即使在该对象的方法内部也是如此

    Inside InstanceMethod3InvokessStaticMethod1-Test.staticMethod1()可以正常工作,这已经足够公平了。但是为什么我们不能直接调用staticMethod1呢

    同样,这不是Javascript的一个特性

    Inside StaticMethod2 InvokingStaticMethod1-这个.staticMethod1()是如何工作的?这个物体的形状是什么

    您需要学习Javascript如何设置
    this
    的值的规则。它通常是根据调用方法的方式设置的(尽管有一些方法可以替代它(如箭头函数)。有关参考信息,请参阅

    在这个特定的问题中,因为您这样调用staticMethod2InvokingStaticMethod1:
    Test.staticMethod2InvokingStaticMethod1();
    ,该函数中的
    this
    指针将设置为
    Test
    ,这意味着您可以通过引用
    this.someOtherStaticMethod()
    ,调用
    Test
    的其他静态方法。这是设置
    this
    的最基本规则。如果调用
    obj.method())
    ,然后在
    方法
    内部,将
    指针设置为
    obj

    在Javascript中要认识到的重要一点是,方法只是一个普通函数,恰好是其他对象的属性。它对任何实例都没有特别的绑定。只有在如何调用方法中指定了绑定时,它才会获得对实例的绑定。这一点的一个例外是不用于方法。在这种情况下,可以使用箭头语法声明函数,它的
    值将在声明时设置为
    的词法值。如果您刚刚开始学习此内容,我建议您跳过箭头函数,直到您掌握了有关
    的所有其他内容它们直到几年前才成为语言的一部分,所以你可以在没有它们的情况下编写完美的Javascript(出于某些目的,它们主要是一种语法快捷方式)

    在静态方法中,this.staticMethod1()有效,但this.instanceMethod1()无效。为什么?我想问题3的答案应该有助于回答这个问题


    是的,正如您所料,答案与3相同。

    谢谢您的详细解释。关于这句话:“该函数中的指针将被设置为Test”。这甚至可以设置为类?@Boney:
    设置为“点之前的任何值”。如果您
    bar.foo()
    然后
    这个
    内部的
    foo
    将引用
    条的值(也有例外。
    条的值可以是任何对象(甚至是一个promitive),包括函数对象(类只是函数)。不确定您为什么期望
    这个.instanceMethod1();
    在静态方法中工作。这在任何其他类系统中都不起作用?!@Bergi。是的,它在任何其他类系统中都不起作用。我的问题可以重新表述为:如果
    this.staticmethod1()
    在静态方法中工作,为什么
    this.instanceMethod1()
    因为
    this.staticmethod1()
    本身对我来说没有意义。