为什么 JavaScript 对象在 ES6 中没有获取数据和方法的副本
Why JavaScript objects doesn't gets copy of data and methods in ES6
面向对象设计的一个共同方面(在大多数语言中,尤其是 Java)是当我们使用构造函数构造新对象时,所有方法和 public/protected 实例变量都会被复制进入对象。例如:
Car myCar = new Car('Corolla', '2015');
现在,如果 Car
class 有 goForward()
或 goBackward()
方法,它们将全部复制到 myCar
对象。
但是我研究过JavaScript里不是这样的。如果这在 JavaScript 中类似,myCar
的原型实际上指向 Car
原型。
根据我的理解,如果我们想使用class-继承作为设计模式,这种数据和方法的复制是最终要求。 Java脚本真的没有这个功能还是我的理解很模糊?新的基于 ES6 class 的结构是否将这件事带入画面?
感谢您澄清我的概念,我对此很困惑,因为我过去一直在 Java 做事情。
在 Java 脚本中,构造函数包含一个 .prototype
属性,其中包含为该对象定义的任何方法(直接赋值给 ES5 中的原型或使用 class
ES6 中的关键字).
然后,当您使用该构造函数实例化一个新对象时,该对象将获得一个指向原型的指针。当在该对象上调用方法时,Java脚本解释器将首先在对象本身上查找具有该名称的 属性,如果在那里找不到,它将搜索原型链。
因此,"copied" 到 Java 脚本中新创建的对象的唯一东西是指向原型的指针。而且,这在 ES5 和 ES6 中的工作方式相同。 ES6 中的 class
语法只是用于执行我们在 ES5 中已经手动执行的操作的新语法(将方法分配给原型对象)。
事实上,如果你愿意,你甚至可以通过 Object.getPrototypeOf()
获得原型。重要的是要认识到新对象包含指向原型对象(而不是副本)的指针。如果对原型对象进行了后续更改,则为 "live" 之前或之后的所有实例化对象都会看到该更改。
class Car {
constructor(brand, model) {
// initialize instance data
this.brand = brand;
this.model = model;
}
goForward() {
console.log("goForward");
}
goBackward() {
console.log("goBackward");
}
}
let c = new Car("Toyota", "Corolla");
console.log(Object.getPrototypeOf(c)); // shows the two methods goForward, goBackward
console.log(c.brand); // "Toyota"
Now if Car class has goForward() or goBackward() methods, all of them will get copied to myCar object.
新对象被赋予了指向原型的指针。方法没有单独复制。
According to my understanding, this copying of data and methods is the ultimate requirement if we want to use class-inheritance as a design pattern.
这不是真的。继承不需要将所有方法复制到新对象。实际上有许多不同的方法可以实现适当的继承。 Java脚本使用原型。 C++ 使用编译时绑定。我自己不知道 Java 的内部结构,但是 this post 指的是一个方法 table,Java 中的每个对象都被赋予一个指向的指针。
Does the new ES6 class-based structure brings this thing into picture?
ES6 不会改变继承在 Javascript 中的内部工作方式。 ES6 只是引入了 class
语法,这是一种声明对象构造函数和方法的不同方式,但它产生的内部结构与我们在 ES5 中手动在原型上声明方法的方式相同。
面向对象设计的一个共同方面(在大多数语言中,尤其是 Java)是当我们使用构造函数构造新对象时,所有方法和 public/protected 实例变量都会被复制进入对象。例如:
Car myCar = new Car('Corolla', '2015');
现在,如果 Car
class 有 goForward()
或 goBackward()
方法,它们将全部复制到 myCar
对象。
但是我研究过JavaScript里不是这样的。如果这在 JavaScript 中类似,myCar
的原型实际上指向 Car
原型。
根据我的理解,如果我们想使用class-继承作为设计模式,这种数据和方法的复制是最终要求。 Java脚本真的没有这个功能还是我的理解很模糊?新的基于 ES6 class 的结构是否将这件事带入画面?
感谢您澄清我的概念,我对此很困惑,因为我过去一直在 Java 做事情。
在 Java 脚本中,构造函数包含一个 .prototype
属性,其中包含为该对象定义的任何方法(直接赋值给 ES5 中的原型或使用 class
ES6 中的关键字).
然后,当您使用该构造函数实例化一个新对象时,该对象将获得一个指向原型的指针。当在该对象上调用方法时,Java脚本解释器将首先在对象本身上查找具有该名称的 属性,如果在那里找不到,它将搜索原型链。
因此,"copied" 到 Java 脚本中新创建的对象的唯一东西是指向原型的指针。而且,这在 ES5 和 ES6 中的工作方式相同。 ES6 中的 class
语法只是用于执行我们在 ES5 中已经手动执行的操作的新语法(将方法分配给原型对象)。
事实上,如果你愿意,你甚至可以通过 Object.getPrototypeOf()
获得原型。重要的是要认识到新对象包含指向原型对象(而不是副本)的指针。如果对原型对象进行了后续更改,则为 "live" 之前或之后的所有实例化对象都会看到该更改。
class Car {
constructor(brand, model) {
// initialize instance data
this.brand = brand;
this.model = model;
}
goForward() {
console.log("goForward");
}
goBackward() {
console.log("goBackward");
}
}
let c = new Car("Toyota", "Corolla");
console.log(Object.getPrototypeOf(c)); // shows the two methods goForward, goBackward
console.log(c.brand); // "Toyota"
Now if Car class has goForward() or goBackward() methods, all of them will get copied to myCar object.
新对象被赋予了指向原型的指针。方法没有单独复制。
According to my understanding, this copying of data and methods is the ultimate requirement if we want to use class-inheritance as a design pattern.
这不是真的。继承不需要将所有方法复制到新对象。实际上有许多不同的方法可以实现适当的继承。 Java脚本使用原型。 C++ 使用编译时绑定。我自己不知道 Java 的内部结构,但是 this post 指的是一个方法 table,Java 中的每个对象都被赋予一个指向的指针。
Does the new ES6 class-based structure brings this thing into picture?
ES6 不会改变继承在 Javascript 中的内部工作方式。 ES6 只是引入了 class
语法,这是一种声明对象构造函数和方法的不同方式,但它产生的内部结构与我们在 ES5 中手动在原型上声明方法的方式相同。