search

Home  >  Q&A  >  body text

javascript - javscript关于类定义方法疑问

各位好,关于类方法的定义有点疑惑,下面是两种方法给Person类定义方法sayHello(),输出结果是一样,但是两者的结构不一样,这两者结构有什么区别呢

    function Person(firstName) {
      this.firstName = firstName;
    }

    Person.prototype.sayHello = function() {

    };

    var person1 = new Person("Alice");
    var person2 = new Person("Bob");

    // call the Person sayHello method.
    person1.sayHello(); // alerts "Hello, I'm Alice"
    person2.sayHello(); // alerts "Hello, I'm Bob"


function Person(firstName) {
      this.firstName = firstName;
      this.sayHello = function() {

    };
    }



    var person1 = new Person("Alice");
    var person2 = new Person("Bob");

    // call the Person sayHello method.
    person1.sayHello(); // alerts "Hello, I'm Alice"
    person2.sayHello(); // alerts "Hello, I'm Bob"

天蓬老师天蓬老师2897 days ago472

reply all(5)I'll reply

  • 天蓬老师

    天蓬老师2017-04-10 15:18:40

    第一种
    sayHello方法定义在Person的prototype中,如果有另一类SuperMan继承之Person,那么新SuperMan将会继承sayHello方法
    第二种
    sayHello只属于Person这个类,如果有另一类SuperMan继承之Person,那么新SuperMan将不会有sayHello方法

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 15:18:40

    第一个例子:

    person1.hasOwnProperty('sayHello')
    //false
    

    第二个例子

    person1.hasOwnProperty('sayHello')
    //true
    

    懂了咩?第一个是在原型中定义的sayHello方法,所以调用的时候是在原型链中调用的。
    第二个在使用new操作符生成实例的时候,将sayHello方法定义到了实例中,所以调用的是自身的方法。

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 15:18:40

    输出结果是一样,但通常使用第一种写法。

    首先对于属性而言,每个实例都可能会有不同,比如你的例子中每个人有不同的名字,但对于方法而言,一般来说每个实例都是相同的,比如你的例子中是输出自己的名字,所以没有必要在每个实例中都添加相同的方法,而是利用原型进行共享。

    为什么可以利用原型共享?在进行属性的GET时(Property resolving),如果自有属性中找不到,就去对象的原型中找,依次类推。利用这一特点,达到共享的目的。

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 15:18:40

    这两种方式区别的在于:
    1、你的“逻辑”是需要实例共享的还是需要各自维护的。
    2、你的“逻辑”是实例在编码阶段就确定(静态逻辑)还是在编码阶段之外才确定(动态逻辑)。

    当你需要在动态执行期改变某个实例的“逻辑”,而非所有实例的“逻辑”,类似继承的概念,这个时候第二种方式才可以实现。

    例如:
    function A() {
    this.f = function(){//默认行为}
    }
    Person.prototype.changeF = function(func){this.f = func}
    a1 = new A();
    a2 = new A();
    a3 = new A();
    a3.changeF(function(){//非默认行为});

    //a1.f == a2.f;
    //a1.f != a3.f;

    ps:一般插件都采用这种方式,即我确定一种方式,然后我还提供你可以在不改变我任何逻辑的前提下,任意插接你的新逻辑进来

    PSS:插入一个图片

    reply
    0
  • 迷茫

    迷茫2017-04-10 15:18:40

    简单的说:
    第一种是new出来的person实例本身是没有sayHello的方法,它在自身没有该方法的时候,会顺着原型链找这个方法,在原型链找到了就会使用,没有就返回undefined

    第二种是new出来的实例本身就有这个sayHello方法,因为这个方法在构造函数就挂在了this身上,不过这种相对于第一种会占用更多内存

    你需要了解下面向对象的构成还有原型链这些东西
    建议看下阮一峰的文章-Javascript的面向对象编程
    我说的可能不是很好理解,还是看大神的文章把

    reply
    0
  • Cancelreply