代码之家  ›  专栏  ›  技术社区  ›  Matt

了解object.create()和new somefunction()之间的区别

  •  360
  • Matt  · 技术社区  · 15 年前

    我最近偶然发现 Object.create() 方法,并尝试推断它与使用 new SomeFunction() 当你想一个一个地使用另一个的时候。

    请考虑以下示例:

    var test = {
      val: 1,
      func: function() {
        return this.val;
      }
    };
    var testA = Object.create(test);
    
    testA.val = 2;
    console.log(test.func()); // 1
    console.log(testA.func()); // 2
    
    console.log('other test');
    var otherTest = function() {
      this.val = 1;
      this.func = function() {
        return this.val;
      };
    };
    
    var otherTestA = new otherTest();
    var otherTestB = new otherTest();
    otherTestB.val = 2;
    console.log(otherTestA.val); // 1 
    console.log(otherTestB.val); // 2
    
    console.log(otherTestA.func()); // 1
    console.log(otherTestB.func()); // 2

    注意,在这两种情况下观察到相同的行为。在我看来,这两种情况之间的主要区别是:

    • 中使用的对象 创建() 实际上形成了新对象的原型,而在 new Function() 声明的属性/函数不构成原型。
    • 不能使用创建闭包 创建() 语法与函数语法相同。这是合乎逻辑的,给定了javascript的词汇(vs块)类型范围。

    以上说法正确吗?我错过什么了吗?你什么时候用一个比另一个?

    编辑:链接到上述代码示例的jsFiddle版本: http://jsfiddle.net/rZfYL/

    10 回复  |  直到 7 年前
        1
  •  232
  •   jithinkmatthew    7 年前

    object.create中使用的对象实际上形成了新对象的原型,与new function()形式一样,声明的属性/函数不构成原型。

    对, Object.create 生成直接从作为第一个参数传递的对象继承的对象。

    使用构造函数函数,新创建的对象继承了构造函数的原型,例如:

    var o = new SomeConstructor();
    

    在上面的例子中, o 直接继承自 SomeConstructor.prototype .

    这里有一个区别,和 创建对象 您可以创建一个不从任何东西继承的对象, Object.create(null); ,另一方面,如果您设置 SomeConstructor.prototype = null; 新创建的对象将从继承 Object.prototype .

    不能使用对象创建闭包。请像使用函数语法那样创建语法。这是合乎逻辑的,给定了javascript的词汇(vs块)类型范围。

    好吧,您可以创建闭包,例如使用属性描述符参数:

    var o = Object.create({inherited: 1}, {
      foo: {
        get: (function () { // a closure
          var closured = 'foo';
          return function () {
            return closured+'bar';
          };
        })()
      }
    });
    
    o.foo; // "foobar"
    

    注意,我说的是ECMAScript第五版 Object.create 方法,而不是Crockford的垫片。

    该方法已开始在最新的浏览器上本地实现,请检查此 compatibility table .

        2
  •  372
  •   Lyubomir    8 年前

    很简单的说, new X Object.create(X.prototype) 另外运行 constructor 功能。(给予) 构造函数 机会 return 应该是表达式结果而不是 this )

    就是这样。:)

    其余的答案只是令人困惑,因为显然没有其他人能理解 new 要么。;)

        3
  •  193
  •   Ray Hulha    9 年前

    以下是两个调用的内部步骤:
    (提示:唯一的区别在步骤3中)


    new Test() :

    1. 创造 new Object() OBJ
    2. 设置 obj.__proto__ Test.prototype
    3. return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value

    Object.create( Test.prototype )

    1. 创造 新对象() OBJ
    2. 设置 Obj.PytoSyp* 测试原型
    3. return obj;

    所以基本上 Object.create 不执行构造函数。

        4
  •  59
  •   limeandcoconut    9 年前

    我来解释一下(更多关于 blog的内容):。

    1. 当您编写 car constructor var car=function()code>时,这是内部情况: 我们有一个 prototype hidden link to function.prototype which is not accessible and one prototype link to car.prototype which is accessible and has an actual constructor. of car. 。function.prototype和car.prototype都有指向 object.prototype的隐藏链接。
    2. 当我们想通过使用 new和 create创建两个等效对象时,我们必须这样做: Honda=new car(); Maruti=object.create(car.prototype) 发生什么事了?

      Honda=new car(); —When you create an object like this then hidden prototype property is pointed to car.prototype 。因此,在这里,本田对象的 prototype->code>将始终是 car.prototype -we don't have any option to change the prototype code>property of the object.如果我想改变我们新创建的对象的原型呢?< BR> maruti=object.create(car.prototype) -当您创建一个类似于此的对象时,您有一个额外的选项来选择您的对象的 prototype property。如果您想将car.prototype作为 prototype. 中的参数传递给函数。如果您不想为您的对象提供任何 prototype ,那么您可以通过 null like this: maruti=object.create(null)

    结论-通过使用方法 object.create You have the freedom to choose your object prototype property.在 new car(); 中,您没有那种自由。

    OO javascript中的首选方式:

    假设我们有两个对象 a=>code>和 b=>code>。

    var a=new object();
    var b=新对象();
    < /代码> 
    
    

    现在,假设ahas some methods whichbalso wants to access.为此,我们需要对象继承(ashould be the prototype ofbonly if we want access to these methods).如果我们检查a和b的原型,那么我们会发现它们共享原型object.prototype。

    object.prototype.isPrototypeof(b);//true
    a.isprototypeof(b);//false(问题出现在这里的图片中)。
    < /代码> 
    
    

    problem-we want objectaas the prototype ofb,but here we created objectbwith the prototypeobject.prototype解决方案-ecmascript 5 involvedobject.create(),to reach such inheritance easyly.如果我们创建对象blike this:。

    var b=object.create(a);
    < /代码> 
    
    

    那么,

    a.isPrototypeof(b);//true(问题已解决,您在对象b的原型链中包含了对象a。)
    < /代码> 
    
    

    因此,如果您正在执行面向对象的脚本编写,那么object.create()对于继承非常有用。

    ):

    1. 当你写作时Car构造函数var Car = function(){},这就是内部情况: A diagram of prototypal chains when creating javascript objects 我们有一个{prototype}隐藏链接Function.prototype不可接近的一个prototype链接到Car.prototype它是可访问的,并且具有constructor属于小型车. function.prototype和car.prototype都有隐藏的链接Object.prototype.
    2. 当我们想通过使用new运算符和create方法然后我们必须这样做:Honda = new Car();Maruti = Object.create(Car.prototype).A diagram of prototypal chains for differing object creation methods 发生什么事了?

      本田=新车();-当你创建一个这样的对象,然后隐藏{原型}属性指向汽车原型. 所以,这里{原型}本田的目标永远是汽车原型-我们没有办法改变{原型}对象的属性。如果我想改变我们新创建的对象的原型呢?
      maruti=object.create(car.prototype)-当您创建这样的对象时,您有一个额外的选项来选择对象的{原型}财产。如果你想把car.prototype作为{原型}然后在函数中将其作为参数传递。如果你不想要的话{原型}然后你就可以通过null这样地:Maruti = Object.create(null).

    结论-使用该方法Object.create你有自由选择你的对象{原型}财产。在new Car();你没有那种自由。

    OO javascript中的首选方法:

    假设我们有两个物体ab.

    var a = new Object();
    var b = new Object();
    

    现在,假设有一些方法也希望访问。为此,我们需要对象继承(应该是只有当我们想要访问这些方法时)。如果我们检查然后我们会发现他们共享原型对象.原型.

    Object.prototype.isPrototypeOf(b); //true
    a.isPrototypeOf(b); //false (the problem comes into the picture here).
    

    问题-我们要对象作为,但在这里我们创建了对象有了原型对象.原型. 解决方案介绍了ECMAScript 5Object.create()以便于继承。如果我们创建对象这样地:

    var b = Object.create(a);
    

    然后,

    a.isPrototypeOf(b);// true (problem solved, you included object a in the prototype chain of object b.)
    

    因此,如果您正在执行面向对象的脚本,那么创建()对继承非常有用。

        5
  •  39
  •   Leopd    12 年前

    这是:

    var foo = new Foo();
    

    var foo = Object.create(Foo.prototype);
    

    非常相似。一个重要的区别是 new Foo 实际上运行构造函数代码,而 Object.create 不会执行以下代码

    function Foo() {
        alert("This constructor does not run with Object.create");
    }
    

    请注意,如果使用的是双参数版本 Object.create() 然后你可以做更强大的事情。

        6
  •  22
  •   user1931858    13 年前

    区别在于所谓的“伪经典与原型继承”。建议在代码中只使用一种类型,而不要混合使用这两种类型。

    在伪经典继承(使用“new”运算符)中,假设您首先定义了一个伪类,然后从该类创建对象。例如,定义一个伪类“person”,然后从“person”创建“alice”和“bob”。

    在原型继承(使用object.create)中,直接创建一个特定的人“alice”,然后使用“alice”作为原型创建另一个人“bob”。这里没有“类”;所有的都是对象。

    在内部,JavaScript使用“原型继承”;“伪经典”方法只是一些甜头。

    this link 两种方法的比较。

        7
  •  21
  •   Pedro del Sol    11 年前
    function Test(){
        this.prop1 = 'prop1';
        this.prop2 = 'prop2';
        this.func1 = function(){
            return this.prop1 + this.prop2;
        }
    };
    
    Test.prototype.protoProp1 = 'protoProp1';
    Test.prototype.protoProp2 = 'protoProp2';
    var newKeywordTest = new Test();
    var objectCreateTest = Object.create(Test.prototype);
    
    /* Object.create   */
    console.log(objectCreateTest.prop1); // undefined
    console.log(objectCreateTest.protoProp1); // protoProp1 
    console.log(objectCreateTest.__proto__.protoProp1); // protoProp1
    
    /* new    */
    console.log(newKeywordTest.prop1); // prop1
    console.log(newKeywordTest.__proto__.protoProp1); // protoProp1
    

    总结:

    1) new 关键词有两件事要注意;

    a)函数用作构造函数

    b) function.prototype 对象被传递到 __proto__ 财产…或者在哪里 第三原型 不支持,它是新对象查找属性的第二个位置

    2) Object.create(obj.prototype) 您正在构造一个对象( obj.prototype )并将其传递给预期的对象..与现在的新对象不同 第三原型 也指向obj.prototype(请参考xj9提供的ans)

        8
  •  10
  •   xj9    15 年前

    内部的 Object.create 这样做:

    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
    

    语法消除了JavaScript使用经典继承的假象。

        9
  •  9
  •   cn007b Dheerendra Kulkarni    8 年前

    相应地 this answer 并且 this video new 关键字执行以下操作:

    1. 创建新对象。

    2. 将新对象链接到构造函数函数( prototype )

    3. 使 this 变量指向新对象。

    4. 使用新对象执行构造函数函数并隐式执行 return this ;

    5. 将构造函数函数名赋给新对象的属性 constructor .

    Object.create 只执行 1st 2nd 台阶!!!!

        10
  •  8
  •   Ted    8 年前

    对象创建变量。


    variant 1 :' new object() '->object constructor without arguments.

    var p1=new object();/'new object()'创建并返回空对象->
    
    var p2=new object();/'new object()'创建并返回空对象->
    
    console.log(p1);//空对象->
    
    console.log(p2);//空对象->
    
    //p1和p2是指向不同对象的指针
    console.log(p1==p2);//false
    
    console.log(p1.prototype);//未定义
    
    //实际上是object.prototype的空对象
    console.log(p1.uu proto_uuu);/
    
    //空对象,p1.\u proto\uuuuu指向该对象
    console.log(object.prototype);/
    
    console.log(p1.uu proto_uu==object.prototype);//true
    
    //空,实际上是object.prototype.\u prototo__
    console.log(p1.uu proto_uuu.u proto_uuu);//空
    
    console.log(object.prototype.uu proto_uuu);//空
    < /代码> 
    
    


    变型2:'new object(person)'->object constructor with argument.

    const person={
    name:'没有名字',
    lastname:'没有姓氏',
    年龄:1岁
    }
    
    //“new object(person)”返回“person”,它是指向对象的指针->
    //->姓名:'no name',姓:'no lastname',年龄:-1
    var p1=新对象(人);
    
    //“new object(person)”返回“person”,它是指向对象的指针->
    //->姓名:'no name',姓:'no lastname',年龄:-1
    var p2=新对象(人);
    
    //person、p1和p2是指向同一对象的指针
    console.log(p1==p2);//真
    console.log(p1==person);//真
    console.log(p2==person);//真
    
    p1.name='john';//将'name'更改为'p1'
    p2.lastname='doe';//将'lastname'更改为'p2'
    person.age=25;//按“person”更改“age”
    
    //打印“p1”、“p2”和“person”时,结果相同,
    //因为它们所指向的对象是相同的
    console.log(p1);/name:'john',lastname:'doe',age:25
    console.log(p2);/name:'john',lastname:'doe',age:25_
    console.log(person);/name:'john',lastname:'doe',age:25
    < /代码> 
    
    


    variant 3.1:'object.create(person)'。使用object.create和简单对象“person”。对象。create(person)'将创建(并返回)新的空对象,并将属性“uu proto_uuuuuu”添加到同一个新的空对象。此属性“proto”将指向对象“person”。

    const person={
    name:'没有名字',
    lastname:'没有姓氏',
    年龄:1岁,
    getinfo:函数getname()。{
    返回`$this.name$this.lastname,$this.age!;
    }
    }
    
    var p1=object.create(人);
    
    var p2=对象.创建(人);
    
    //“p1.\u proto\uuuuuu”和“p2.\u proto\uuuuu”指向
    //同一对象->'个人'
    //name:'no name',lastname:'no lastname',age:-1,getinfo:[函数:getname]
    console.log(p1.协议);
    console.log(p2.协议);
    console.log(p1.uu proto_uu==p2.u proto_uuuu);//真
    
    console.log(person.uu proto_uuu);/(即object.prototype)
    
    //“person”、“p1”和“p2”不同
    console.log(p1==person);//false
    console.log(p1==p2);//false
    console.log(p2==person);//false
    
    //name:'no name',lastname:'no lastname',age:-1,getinfo:[函数:getname]
    主控台日志(人);
    
    console.log(p1);//空对象-
    
    console.log(p2);//空对象-
    
    //向对象“p1”添加属性
    //(与对象“person”中同名的属性)
    p1.name='john';
    p1.lastname='doe';
    P1年龄=25;
    
    //向对象“p2”添加属性
    //(与对象“person”中同名的属性)
    p2.name='汤姆';
    p2.lastname='哈里森';
    年龄=38岁;
    
    //name:'no name',lastname:'no lastname',age:-1,getinfo:[函数:getname]
    主控台日志(人);
    
    //姓名:'John',姓:'Doe',年龄:25
    控制台日志(p1);
    
    //姓名:'Tom',姓:'Harrison',年龄:38
    控制台日志(p2);
    
    //由“uuu proto_uuuu”(从“p1”到“person”的链接)使用,
    //人员的函数“getinfo”
    console.log(p1.getinfo());//john doe,25!
    
    //由“uuu proto_uuuu”(从“p2”到“person”的链接)使用,
    //人员的函数“getinfo”
    console.log(p2.getinfo());//汤姆·哈里森,38岁!
    < /代码> 
    
    


    variant 3.2:'object.create(object.prototype)'。使用object.create和内置对象->'object.prototype''。object.create(object.prototype)将创建(并返回)新的空对象,并将属性“uu proto_uuuuuuuu”添加到同一个新的空对象。此属性“proto”将指向对象“object.prototype”。

    /'object.create(object.prototype)':
    / / 1。创建并返回空对象->。
    / / 2。添加到“p1”属性“uu proto_uuuuu”,该属性链接到“object.prototype”
    var p1=object.create(object.prototype);
    
    //“object.create(object.prototype)”:
    / / 1。创建并返回空对象->。
    / / 2。添加到“p2”属性“proto”中,链接到“object.prototype”
    var p2=object.create(object.prototype);
    
    console.log(p1);/
    
    console.log(p2);/
    
    console.log(p1==p2);//false
    
    console.log(p1.prototype);//未定义
    
    console.log(p2.prototype);//未定义
    
    console.log(p1.uu proto_uu==object.prototype);//true
    
    console.log(p2.uu proto_uu==object.prototype);//true
    < /代码> 
    
    


    variant 4:'new somefunction()',

    构造函数函数“person”中的“this” //表示新实例, //将由“new person(…)”创建 //并隐式返回 职能人员(姓名、姓氏、年龄){ this.name=名称; this.lastname=姓; 这个年龄=年龄; //————————————————————————————————————————————————————————————————————————————————————————————————————————————————-- / /!---仅用于演示--- //如果将函数“getinfo”添加到 //构造函数函数“person”, //那么所有实例都将有一个“getinfo”函数的副本! / / //this.getinfo:函数getinfo()。{ //返回this.name+“”+this.lastname+“,”+this.age+“!”; //} //————————————————————————————————————————————————————————————————————————————————————————————————————————————————-- } //“person.prototype”是空对象 //(在添加函数“getinfo”之前) console.log(person.prototype);//人 //将“getinfo”添加到“person.prototype”, //实例的属性“uu proto_uuuu”, //将可以访问函数“getinfo”。 //使用这种方法,实例不需要 //每个实例的函数“getinfo”的副本。 person.prototype.getinfo=函数getinfo()。{ 返回this.name+“”+this.lastname+“,”+this.age+“!”; } //函数“getinfo”添加到“person.prototype”后 console.log(person.prototype);//person getinfo:[函数:getinfo] //创建实例“p1” var p1=新人(“John”,“Doe”,25); //创建实例“p2” var p2=新人(“汤姆”,“哈里森”,38); //人名:'john',姓:'doe',年龄:25 控制台日志(p1); //人名:'Tom',姓:'Harrison',年龄:38 控制台日志(p2); //“p1.\u proto\uuuuuuu”指向“person.prototype” console.log(p1.uuu proto_uuu);//person getinfo:[函数:getinfo] //“p2.\u proto\uuuuuuu”指向“person.prototype” console.log(p2.uuu proto_uuuu);//person getinfo:[函数:getinfo] console.log(p1.uu proto_uu==p2.u proto_uuuu);//真 //“p1”和“p2”指向不同的对象(“person”的实例) console.log(p1==p2);//false //“p1”通过其属性“uuu proto_uuuuuuuuuuu”到达“person.prototype.getinfo” //并将“getinfo”与“p1”-实例的数据一起使用 console.log(p1.getinfo());//john doe,25! //“p2”通过其属性“uuu proto_uuuuuuuuuuuu”到达“person.prototype.getinfo” //并将“getinfo”与“p2”-实例的数据一起使用 console.log(p2.getinfo());//汤姆·哈里森,38岁! < /代码>

    R没有参数。

    var p1 = new Object(); // 'new Object()' create and return empty object -> {}
    
    var p2 = new Object(); // 'new Object()' create and return empty object -> {}
    
    console.log(p1); // empty object -> {}
    
    console.log(p2); // empty object -> {}
    
    // p1 and p2 are pointers to different objects
    console.log(p1 === p2); // false
    
    console.log(p1.prototype); // undefined
    
    // empty object which is in fact Object.prototype
    console.log(p1.__proto__); // {}
    
    // empty object to which p1.__proto__ points
    console.log(Object.prototype); // {}
    
    console.log(p1.__proto__ === Object.prototype); // true
    
    // null, which is in fact Object.prototype.__proto__
    console.log(p1.__proto__.__proto__); // null
    
    console.log(Object.prototype.__proto__); // null
    

    enter image description here


    变型2:新对象(人)'->带参数的对象构造函数。

    const person = {
        name: 'no name',
        lastName: 'no lastName',
        age: -1
    }
    
    // 'new Object(person)' return 'person', which is pointer to the object ->
    //  -> { name: 'no name', lastName: 'no lastName', age: -1 }
    var p1 = new Object(person);
    
    // 'new Object(person)' return 'person', which is pointer to the object ->
    //  -> { name: 'no name', lastName: 'no lastName', age: -1 }
    var p2 = new Object(person);
    
    // person, p1 and p2 are pointers to the same object
    console.log(p1 === p2); // true
    console.log(p1 === person); // true
    console.log(p2 === person); // true
    
    p1.name = 'John'; // change 'name' by 'p1'
    p2.lastName = 'Doe'; // change 'lastName' by 'p2'
    person.age = 25; // change 'age' by 'person'
    
    // when print 'p1', 'p2' and 'person', it's the same result,
    // because the object they points is the same
    console.log(p1); // { name: 'John', lastName: 'Doe', age: 25 }
    console.log(p2); // { name: 'John', lastName: 'Doe', age: 25 }
    console.log(person); // { name: 'John', lastName: 'Doe', age: 25 }
    

    enter image description here


    变型3.1:对象.创建(人)'.使用object.create和简单对象“person”。对象。create(person)'将创建(并返回)新的空对象,并将属性“uu proto_uuuuuu”添加到同一个新的空对象。此属性“proto”将指向对象“person”。

    const person = {
            name: 'no name',
            lastName: 'no lastName',
            age: -1,
            getInfo: function getName() {
               return `${this.name} ${this.lastName}, ${this.age}!`;
        }
    }
    
    var p1 = Object.create(person);
    
    var p2 = Object.create(person);
    
    // 'p1.__proto__' and 'p2.__proto__' points to
    // the same object -> 'person'
    // { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
    console.log(p1.__proto__);
    console.log(p2.__proto__);
    console.log(p1.__proto__ === p2.__proto__); // true
    
    console.log(person.__proto__); // {}(which is the Object.prototype)
    
    // 'person', 'p1' and 'p2' are different
    console.log(p1 === person); // false
    console.log(p1 === p2); // false
    console.log(p2 === person); // false
    
    // { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
    console.log(person);
    
    console.log(p1); // empty object - {}
    
    console.log(p2); // empty object - {}
    
    // add properties to object 'p1'
    // (properties with the same names like in object 'person')
    p1.name = 'John';
    p1.lastName = 'Doe';
    p1.age = 25;
    
    // add properties to object 'p2'
    // (properties with the same names like in object 'person')
    p2.name = 'Tom';
    p2.lastName = 'Harrison';
    p2.age = 38;
    
    // { name: 'no name', lastName: 'no lastName', age: -1, getInfo: [Function: getName] }
    console.log(person);
    
    // { name: 'John', lastName: 'Doe', age: 25 }
    console.log(p1);
    
    // { name: 'Tom', lastName: 'Harrison', age: 38 }
    console.log(p2);
    
    // use by '__proto__'(link from 'p1' to 'person'),
    // person's function 'getInfo'
    console.log(p1.getInfo()); // John Doe, 25!
    
    // use by '__proto__'(link from 'p2' to 'person'),
    // person's function 'getInfo'
    console.log(p2.getInfo()); // Tom Harrison, 38!
    

    enter image description here


    变型3.2:对象.创建(对象.原型)'.使用object.create和内置对象->'object.prototype''。object.create(object.prototype)将创建(并返回)新的空对象,并将属性“uu proto_uuuuuuuu”添加到同一个新的空对象。此属性“proto”将指向对象“object.prototype”。

    // 'Object.create(Object.prototype)' :
    // 1. create and return empty object -> {}.
    // 2. add to 'p1' property '__proto__', which is link to 'Object.prototype'
    var p1 = Object.create(Object.prototype);
    
    // 'Object.create(Object.prototype)' :
    // 1. create and return empty object -> {}.
    // 2. add to 'p2' property '__proto__', which is link to 'Object.prototype'
    var p2 = Object.create(Object.prototype);
    
    console.log(p1); // {}
    
    console.log(p2); // {}
    
    console.log(p1 === p2); // false
    
    console.log(p1.prototype); // undefined
    
    console.log(p2.prototype); // undefined
    
    console.log(p1.__proto__ === Object.prototype); // true
    
    console.log(p2.__proto__ === Object.prototype); // true
    

    enter image description here


    变型4:新建someFunction()

    // 'this' in constructor-function 'Person'
    // represents a new instace,
    // that will be created by 'new Person(...)'
    // and returned implicitly
    function Person(name, lastName, age) {
    
        this.name = name;
        this.lastName = lastName;
        this.age = age;
    
        //-----------------------------------------------------------------
        // !--- only for demonstration ---
        // if add function 'getInfo' into
        // constructor-function 'Person',
        // then all instances will have a copy of the function 'getInfo'!
        //
        // this.getInfo: function getInfo() {
        //  return this.name + " " + this.lastName + ", " + this.age + "!";
        // }
        //-----------------------------------------------------------------
    }
    
    // 'Person.prototype' is an empty object
    // (before add function 'getInfo')
    console.log(Person.prototype); // Person {}
    
    // With 'getInfo' added to 'Person.prototype',
    // instances by their properties '__proto__',
    // will have access to the function 'getInfo'.
    // With this approach, instances not need
    // a copy of the function 'getInfo' for every instance.
    Person.prototype.getInfo = function getInfo() {
        return this.name + " " + this.lastName + ", " + this.age + "!";
    }
    
    // after function 'getInfo' is added to 'Person.prototype'
    console.log(Person.prototype); // Person { getInfo: [Function: getInfo] }
    
    // create instance 'p1'
    var p1 = new Person('John', 'Doe', 25);
    
    // create instance 'p2'
    var p2 = new Person('Tom', 'Harrison', 38);
    
    // Person { name: 'John', lastName: 'Doe', age: 25 }
    console.log(p1);
    
    // Person { name: 'Tom', lastName: 'Harrison', age: 38 }
    console.log(p2);
    
    // 'p1.__proto__' points to 'Person.prototype'
    console.log(p1.__proto__); // Person { getInfo: [Function: getInfo] }
    
    // 'p2.__proto__' points to 'Person.prototype'
    console.log(p2.__proto__); // Person { getInfo: [Function: getInfo] }
    
    console.log(p1.__proto__ === p2.__proto__); // true
    
    // 'p1' and 'p2' points to different objects(instaces of 'Person')
    console.log(p1 === p2); // false
    
    // 'p1' by its property '__proto__' reaches 'Person.prototype.getInfo' 
    // and use 'getInfo' with 'p1'-instance's data
    console.log(p1.getInfo()); // John Doe, 25!
    
    // 'p2' by its property '__proto__' reaches 'Person.prototype.getInfo' 
    // and use 'getInfo' with 'p2'-instance's data
    console.log(p2.getInfo()); // Tom Harrison, 38!
    

    enter image description here

    推荐文章