Javascript 与JS中类内函数的混淆

Javascript 与JS中类内函数的混淆,javascript,Javascript,我在学习JS的课程,如果你看下面的代码 class Car{ drive(speed) { console.log('Drive at '+ speed) } } const car1 = new Car(); 我在Car类中定义了函数drive(),很明显,drive()会自动附加到Car.prototype,它确保有一个drive()的副本,问题是如果我们创建Car类的新实例,那么drive()会复制到car1,如果不是,如何可能拥有一个drive()副本,并通过传递

我在学习JS的课程,如果你看下面的代码

class Car{
  drive(speed) {
     console.log('Drive at '+ speed)
   }
}

const car1 = new Car();

我在Car类中定义了函数
drive()
,很明显,
drive()
会自动附加到Car.prototype,它确保有一个
drive()
的副本,问题是如果我们创建Car类的新实例,那么drive()会复制到
car1
,如果不是,如何可能拥有一个
drive()
副本,并通过传递参数获得不同的结果。

是的
Car类
实例上可用,您可以在
Car类的任何实例上调用
drive
函数时传递值

等级车{
驱动(速度){
console.log('以'+速度行驶)
}
}
const car1=新车();

car1.drive('50kmph')
原型中创建的所有内容都将在类的所有实例之间共享。请记住,在
prototype
中定义的方法中,通常是定义类的行为(应该在所有实例之间共享)

现在,当您定义
Car
类的第二个实例时,第一个实例和第二个实例共享
drive
方法。但这并不意味着他们不能用不同的值调用方法:

class Car {
    drive(speed) {
        console.log('Drive at '+ speed)
    }
}

const car1 = new Car();
car1.drive('10mph'); // ---> Will log "Drive at 10mph"

const car2 = new Car();
car2.drive('15mph'); // ---> Will log "Drive at 15mph"

这是一种困惑,因为我们在课堂上添加了太多的“糖”,却不知道发生了什么

您的类是使用ES6定义的

class Car {
  drive(speed) {
    console.log('Drive at ' + speed)
  }
}
接下来要做的是使用类构造一个对象,使用new

第一个问题是new关键字的作用是什么

  • 将创建一个新对象,该对象继承自
    Car
    prototype
  • 附加到此新创建的对象
因此,通过执行
const car1=新车()
,您将获得一个新对象,在该对象的原型中,您将获得
驱动
功能

function Car() {}

Car.prototype.drive = function (speed) { console.log(speed); }
在ES5中,您的类是使用构造函数编写的

function Car() {}

Car.prototype.drive = function (speed) { console.log(speed); }
现在,您可以做:
console.log(Car.prototype.constructor),您将看到所示的构造函数是Car

如果要在ES6中创建子类,可以使用extends关键字,但在ES5中实际发生的是:

Function SuperFastCar() {}

SuperFastCar.prototype = Object.create(Car.prototype);
SuperFastCar.prototype.turbo = function (maxSpeed) { console.log(maxSpeed); }
SuperFastCar.prototype.constructor = SuperFastCar;

Object.create
使用提供的对象作为原型创建新对象。另外,我们需要覆盖
构造函数
,如果不是
Car
,则会为
SuperFastCar

显示构造函数函数。谢谢您的友好回答,看,如果我创建了car2对象,那么car2将拥有自己的drive()副本。我的意思是,每次我创建新对象时,每个对象都会有自己的驱动器(),因为每个对象都有自己的驱动器speed@user11807902
drive
是无状态函数,它只是console.log,因此您的
Car
实例不包含任何值,您将在console.log中获得在
drive
函数中传递的任何值,这就是
prototype
链的工作方式。首先,将检查
car1
是否有
drive
属性。如果它不存在,将在
Car.prototype
中查找。如果在那里找不到它,将在
Object.prototype
中搜索它,因为
Object.getPrototypeOf(Car.prototype)==Object.prototype
(类似
toString()
)的方法@adiga,看,如果我创建更多的Car类对象,每个对象都会有自己的drive()原始副本吗?不,不会。如果您更新
Car.prototype.drive=
,它将影响所有
Car
对象@adiga的可能副本,但是通过在Car.prototype中为所有对象创建一个drive()副本,我们如何为每个方法自定义drive(),例如car1的速度为90,car2的速度为100,因此drive()将输出各种结果。这是否意味着每个对象都可以访问fresh drive(),即使只有一个drive()副本。希望你明白我的意思谢谢你友好的回答,是的,除了一件事,一切都很清楚。好的,将函数放入原型的原因是为了确保有一个函数实例可以节省内存。好的,但假设我们有带参数的函数,每次我们用不同的参数创建对象时,输出将不同。让我困惑的是,car2是如何访问fresh drive()的,因为car1已经使用了不同的参数。希望很清楚谢谢你友好的回答,是的,除了一件事,一切都很清楚。好的,将函数放入原型的原因是为了确保有一个函数实例可以节省内存。好的,但假设我们有带参数的函数,每次我们用不同的参数创建对象时,输出将不同。让我困惑的是,car2是如何访问fresh drive()的,因为car1已经使用了不同的参数。希望它是清楚的,就像我说的,每次你用一个新的对象创建一个新的对象,在这个对象的原型中,函数(驱动)被添加,它不介意函数是否有参数。此外,函数执行没有状态,除非在函数中使用类atributes。但正如我所说的,这是新创建的对象,所以,它没有问题。好的,完美的,你知道,只是最后一个问题,为什么你在函数Car之外声明Car.prototype.drive=function(speed){console.log(speed);}?这就是ES6在类内声明函数时为你做的。是的,我知道,但为什么?如果我们把Car.prototype.drive=function(speed){console.log(speed);}放在函数里面会怎么样?我觉得不好,但我不知道为什么?:)