对象创建和原型委派的使用

时间:2017-12-23 18:34:54

标签: javascript prototype

在下面的示例中,我有一个简单的Spy对象。我想创建另一个用原始对象设置原型的对象,所以我使用了Object.create()。
现在我有一个新对象,它只有原始的一些属性(' 代码'' 呼吸'方法)。所有其他属性(对象 - ' 名称'和数组 - ' 敌人')都在 _proto中 _ object,我可以使用它,因为它们被委托给原始对象。到现在为止还挺好。

棘手的部分是,如果我更改 _proto _对象中包含的AnotherSpy中的任何内容(例如,对象名称),那些更改将反映在所有从原始间谍创建的对象,包括他自己!

我也尝试使用JSON.parse()创建一个新对象,但是这样我有了一个新对象,它只能访问之前在 _proto _对象中的两件事 - 敌人名称对象的数组,无法使用原始对象的任何方法(' 呼吸& #39;方法)。



let Spy = {
  code: '007',
  enemies: ['Dr.No'],
  fullName: {
    firstName: 'James',
    lastName: 'Bond'
  },
  breath: function() {
    console.log('im breathing..')
  }
}

// original Spy breathing
Spy.breath(); // ok, he breaths

// create a new object with Object.create()
let OtherSpy = Object.create(Spy);

console.log(OtherSpy) // have direct access to properties 'code' and function 'breath' and all the others throught the __proto__ object

// Make OtherSpy breath
OtherSpy.breath(); // ok, he is breathing

// so far so good. Lets change the property and function on the OtherSpy
OtherSpy.code = '008';
OtherSpy.breath = () => {
  console.log('im a new breathing')
};

OtherSpy.breath(); // ok, he's breathing differently

console.log(Spy.code); // 007 ok, original spy has the same code
Spy.breath() // ok, he stills breath in the same way.

// change the object 'name' of the OtherSpy
OtherSpy.fullName.firstName = 'Enemy';

// That change will reflect also on the original Spy...
console.log(Spy.fullName.firstName); // Enemy !!!!

// Trying in another way: 
let NewSpy = JSON.parse(JSON.stringify(Spy));
console.log('NewSpy')
console.log(NewSpy) // now i dont have access to methods in the original object
NewSpy.breath() // Uncaught TypeError: NewSpy.breath is not a function




似乎 _proto _对象中包含的所有属性都在使用该原型链的所有对象中共享。

除了非常欣赏解释的这些棘手的部分之外,我想知道在JavaScript中创建对象的正确方法(不使用ES6类)以获得原型委派的优势 并且能够修改派生对象的属性和功能,而不会弄乱原始对象或任何其他派生对象。

提前致谢!

2 个答案:

答案 0 :(得分:0)

嵌套属性有点无用,所以你可以通过使用getter / setter来展平它:

const Spy = {
  firstName: "Agent",
  lastName: "Unnamed",

  breath(){
    console.log(`${this.fullName} is breathing`);
  },

  get fullName(){
     return this.firstName + " " + this.lastName;
  },
  set fullName(name){
     const [first, last] = name.split(" ");
     this.firstName = first;
     this.lastName = last;
  }
 };


  const james = Object.create(Spy);
  james.fullName = "James Bond";
  james.breath();
  console.log(james.fullName, james.firstName, james.lastName);

答案 1 :(得分:0)

另一种方法是在构造函数中构造name对象:

 function Spy(name, code, enemies){
   this.name = (([first, last]) => ({first, last}))(name.split(" "));
   this.name.toString = () => name;
   this.code = code;
   this.enemies = enemies;
 }

 Spy.prototype = {
   breath(){
     console.log(`${this.name} is breathing`);
   }
 }

可用作:

 const james = new Spy("James Bond", "007", ["Dr. No"]);
 james.breath();
 console.log(james.name, "" + james.name);