我是Codeyear同事,不幸的是原型对象概念没有被解释。我谷歌并发现tutorial。在学习之后,我的理解是说我们使用原型对象继承来节省内存并在对象之间共享公共属性。 我是对的吗?如果是的话,您认为以下代码不是不良做法。由于汽车制造商已经定义了价格,速度和& getPrice,为什么我们需要再次定义相同的东西,因为我们正在使用继承的概念。请解释 。下面是代码。
function Car( listedPrice ) {
var price = listedPrice;
this.speed = 0;
this.getPrice = function() {
return price;
};
}
Car.prototype.accelerate = function() {
this.speed += 10;
};
function ElectricCar( listedPrice ) {
var price = listedPrice;
this.speed = 0;
this.getPrice = function() {
return price;
};
}
ElectricCar.prototype = new Car(); // Please also explain why car constructor
// is not thowing error since we are not passing
// listedPrice parameter
myElectricCar = new ElectricCar(500);
console.log(myElectricCar instanceof Car);
答案 0 :(得分:3)
构造函数和原型是两个独立的概念。当您使用ElectricCar.prototype = new Car();
应用原型继承时,它仅继承在对象及其原型上定义的方法,而不是构造函数本身。
您可以通过一些快速console.log()
来电实际查看其工作方式:
console.log(ElectricCar);
console.log(ElectricCar.prototype);
console.log(ElectricCar.prototype.__proto__);
返回:
[Function: ElectricCar]
{ speed: 0, getPrice: [Function] }
{ accelerate: [Function] }
第一行是构造函数。
第二个是实际原型,由上面的ElectricCar.prototype = new Car();
设置。请记住,在Car
的构造函数中,设置了this.speed
和this.getPrice
,这解释了ElectricCar.prototype.speed
和ElectricCar.prototype.getPrice
的值。
可能最不清楚的是最后一行ElectricCar.prototype.__proto__
。这是原型的原型。 Car
个对象有一个prototype
对象,其中定义了accelerate
。此原型将复制到其内部ElectricCar
属性中的__proto__
原型。这称为prototype chaining。
因为构造函数不是原型的一部分,并且原型就是您继承的所有内容,所以Car
的构造函数已被复制并粘贴到ElectricCar
中。正如您所指出的,有一些更简洁的方法可以做到这一点。这是另一种选择:
function ElectricCar( listedPrice ) {
Car.apply(this, arguments);
}
ElectricCar.prototype = new Car();
有关详细信息,请参阅apply
。
至于你的最后一个问题(为什么不new Car()
抛出错误),正如其他答案所说,这就是JavaScript的工作方式。如果为函数提供的参数少于参数,则任何未设置(可以这么说)的参数都将设置为undefined
。为了证明:
function returnMe(a) {
return a;
}
console.log(returnMe(5));
console.log(returnMe(2+2));
console.log(returnMe());
console.log(returnMe(undefined));
这将返回:
5
4
undefined
undefined
正如您所看到的,undefined
实际上是一个可以传递的变量(如returnMe(undefined)
中所示)。有关详情,请参阅undefined
。
答案 1 :(得分:0)
getPrice
可以在其外部范围内创建一个price
var的闭包,有效地使price
为私有成员,为每个不同的实例分隔 ,只有这个功能可以访问。
构造函数不会抛出错误,因为在JavaScript中向函数提供参数绝不是必需的。您可以随意提供,只要有命名参数,首先从您提供的列表中分配这些名称。