我知道,为了将属性绑定到函数,您需要将其添加到其原型中。例如:
function Animal(name) {
this.name = name;
};
Animal.prototype.number = 20;
Animal.prototype.bark = function() {console.log('Woof')};
let mike = new Animal('Mike');
console.log(mike.number)
mike.bark();
也许这是一个非常幼稚的问题,但是为什么不允许将属性绑定到函数本身呢?例如,执行以下操作:
function Animal(name) {
this.name = name;
};
Animal.bark = function() {console.log('Woof')};
Animal.number = 20;
let mike = new Animal('Mike');
console.log(mike.number)
mike.bark();
JavaScript 中的对象使用原型继承。每个对象都继承自其他对象或null
。这条链继续 - 所有对象最终都继承自null
。
如果一个对象继承自另一个对象,则父对象上可用的所有属性都将在子对象上可用(除非子对象定义具有相同名称的属性,从而有效地隐藏父对象上的名称)。
如果动物的实例继承自动物本身,例如
function Animal(name) {
this.name = name;
};
Animal.bark = function() {console.log('Woof')};
Animal.number = 20;
然后 Animal 的实例将从function Animal
继承,这是一个函数 - 并且将是函数,也将继承.call
、.apply
等等。这几乎从来都不是开发人员想要的。
拥有一个实例继承的单独可控对象更有意义,因此决定通过<functionName>.prototype
使该对象可引用。
原型链为:
instance <- Animal.prototype <- Object.prototype
和
Animal <- Function.prototype <- Object.prototype
让实例也继承自Function.prototype
并且是函数是没有意义的。人们几乎总是希望普通对象作为实例,而不是可调用的函数。
将Animal.prototype
与Animal
分开的另一个好处是,您可以在原型上同时具有属性,在函数或类本身上具有属性,这是将实例值和方法与实用程序值和函数(与类相关联,但与任何实例无关)的好方法。
function Animal(name) {
this.name = name;
};
Animal.prototype.bark = function() {console.log(this.name + ' says Woof')};
Animal.checkIsAnimal = function(possibleAnimal) {
console.log('Is this an animal? ' + (possibleAnimal instanceof Animal));
};
const mike = new Animal('Mike');
Animal.checkIsAnimal({});
Animal.checkIsAnimal(mike);