为什么JavaScript对象没有';t获取ES6中数据和方法的副本
面向对象设计(在大多数语言中,尤其是Java中)的一个常见方面是,当我们使用构造函数构造新对象时,所有方法和公共/受保护的实例变量都被复制到对象中。例如:为什么JavaScript对象没有';t获取ES6中数据和方法的副本,javascript,class,design-patterns,ecmascript-6,es6-class,Javascript,Class,Design Patterns,Ecmascript 6,Es6 Class,面向对象设计(在大多数语言中,尤其是Java中)的一个常见方面是,当我们使用构造函数构造新对象时,所有方法和公共/受保护的实例变量都被复制到对象中。例如: Car myCar = new Car('Corolla', '2015'); 现在,如果Car类具有goForward()或goBackward()方法,则所有这些方法都将被复制到myCar对象 但就我所研究的JavaScript而言,情况并非如此。如果这在JavaScript中是类似的,myCar的原型实际上指向Car原型 根据我的理解
Car myCar = new Car('Corolla', '2015');
现在,如果Car
类具有goForward()
或goBackward()
方法,则所有这些方法都将被复制到myCar
对象
但就我所研究的JavaScript而言,情况并非如此。如果这在JavaScript中是类似的,myCar
的原型实际上指向Car
原型
根据我的理解,如果我们想使用类继承作为设计模式,那么这种数据和方法的复制是最终的要求。JavaScript真的缺少这个特性,还是我的理解很模糊?新的基于ES6类的结构是否将这一点带入了人们的视野
感谢您澄清我的概念,我对此感到非常困惑,因为我过去一直在用Java做事情。在Javascript中,构造函数包含一个
.prototype
属性,该属性包含为该对象定义的任何方法(在ES5中直接分配给原型,或者在ES6中使用class
关键字)
然后,当您使用该构造函数实例化一个新对象时,该对象将被赋予一个指向原型的指针。当对该对象调用一个方法时,Javascript解释器将首先在该对象本身上查找具有该名称的属性,如果在那里找不到,它将搜索原型链
因此,在Javascript中,“复制”到新创建对象的唯一内容是指向原型的指针。这在ES5和ES6中的作用相同。ES6中的class
语法只是我们在ES5中手动执行的新语法(将方法分配给原型对象)
事实上,如果需要,您甚至可以使用Object.getPrototypeOf()
获取原型。重要的是要认识到新对象包含指向原型对象的指针(而不是副本)。如果对原型对象进行后续更改,则它是“活动的”,并且之前或之后的所有实例化对象都将看到该更改
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"
现在,如果Car类有goForward()或goBackward()方法,则所有这些方法都将被复制到myCar对象
给新对象一个指向原型的指针。这些方法不会单独复制
根据我的理解,如果我们想使用类继承作为设计模式,那么这种数据和方法的复制是最终的要求
<>这不是真的。继承不需要复制所有方法到新对象。实际上有很多不同的方法来实现正确的继承。JavaScript使用一个原型。C++使用编译时绑定。我自己不知道java的内部结构,但引用了一个方法表,它给java中的每个对象提供了指针T。o
新的基于ES6类的结构是否将这一点带入了人们的视野
ES6并没有改变继承在Javascript内部的工作方式。ES6只是引入了
类
语法,这是一种声明对象构造函数和方法的不同方式,但它产生了与我们在ES5原型上手动声明方法相同的内部结构。我不太明白这个问题。在大多数情况下OOP语言,当你实例化一个类的新实例时,方法不会被复制到它,只是设置了对象的类,当你调用一个方法时,有一种机制可以在相关的类及其超类中搜索它。这在javascript中也是一样的,只是你有一个原型而不是class.ES6类只是语法糖,它相当于在纯JS中做一辆新车(…)
,看一看——事实上你的理解似乎太模糊了。在没有严肃的OOP语言中,每个方法都被复制到每个实例:在Java中,编译器做了一些魔术,让你调用myCar.goBackward()
,而在JavaScript中,它是一个完全透明的运行时构造,允许您执行myCar.goBackward()
。它根本不影响设计-它只是更灵活而已,ES6class
没有带来新的结构,它只带来了新的语法-继承如何工作的概念没有改变。