【问题标题】:Calling a method of an object's prototype调用对象原型的方法
【发布时间】:2017-02-17 20:36:11
【问题描述】:

我是 JS 新手,遇到以下问题:

为什么这不起作用/这段代码在做什么?

var Test = {};
Test.prop = "test property";

Test.Class1 = function () {
}

Test.Class1.prototype = {
    m1: function() {
        console.log(this.prop);
    }
}

Test.Class1.m1();

我对这段代码的理解是:

  1. 创建一个名为 Test 的新对象
  2. 将属性 prop 添加到 Test
  3. Test 中创建一个名为 Class1 的新对象
  4. 将方法 m1 添加到 Class1
  5. Test中调用Class1m1方法

【问题讨论】:

    标签: javascript oop prototype


    【解决方案1】:

    在 JavaScript 中,即使是函数的原型属性也是一个对象。在创建原型是您定义的对象之前,Test1.Class1.prototype 只是一个常规对象。基本上它的工作方式与以下代码 sn-p 相同:

    var Test1 = { prototype { m1: function() {} } };
    // You're trying to call an undefined function!
    Test.m1();
    
    // This is fine
    Test1.prototype.m1();
    

    另一方面,当您使用new 运算符时,您正在创建一个新对象,其原型是构造函数的集合。 魔法从这里开始:

    var Test1 = function() {};
    Test1.prototype = {
        doStuff: function() {}
    };
    
    var object1 = new Test1();
    // This works!
    object1.doStuff();
    

    当您访问一个属性时,JavaScript 的运行时会检查该对象以查找是否有一个名为 doStuff 的函数,否则它会在对象的原型上查找它,否则它会在原型的原型上查找,等等。 .

    实际上new 运算符是syntactic sugar。 ECMA-Script 5 引入了Object.create,让一切变得更加清晰:

    var Test1 = {
        doStuff: function() {
        }
    };
    
    // The first parameter of Object.create is
    // the object that's going to be the prototype of
    // Test1 object!
    var object1 = Object.create(Test1);
    // This works too!
    object1.doStuff();
    

    也许您应该查看其他问答:How does JavaScript .prototype work?

    【讨论】:

      【解决方案2】:

      您需要先创建原型的实例,然后才能使用其方法:

      var instance = new Test.Class1();
      console.log(instance.m1());
      

      即便如此,Test.prop 不是实例的一部分,m1 也无法访问

      编辑:这是一个工作示例:

      var test = function() {
        this.prop = "A property";
      }
      
      test.prototype.m1 = function() {
        console.log(this.prop);
      }
      
      var instance = new test();
      console.log(instance.m1());
      

      【讨论】:

        【解决方案3】:

        prototype 链接仅适用于使用 new 运算符创建的实例。

        否则你将不得不显式调用原型来访问该方法。

        let testClass = new Test.Class1();
        
        testClass.m1();
        

        另外,因为您正在尝试访问 prop 属性。

        Test.Class1.prototype = {
            m1: function() {
                console.log(this.prop);
            }
        }
        

        呼叫站点是Test.Class1prop 应该是Test.Class1 的一部分,而不是Test 的一部分

        【讨论】:

        • 不仅如此。 Object.create 呢:D
        【解决方案4】:

        我更改了事物的名称,但这应该可以。

        var Person = function(){
            this.message = "Hello, world!";
        };
        
        Person.prototype = Object.create(Object.prototype);
        Person.prototype.constructor = Person;
        
        Person.prototype.greet = function(){
            console.log(this.message);
            alert(this.message);
        }; 
        
        var tom = new Person();
        tom.greet();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-13
          • 1970-01-01
          • 1970-01-01
          • 2014-05-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多