使用函数继承时,“instanceof”的等价物是什么?
What would be the equivalent of `instanceof` when using functional inheritance?
在 JavaScript 中有一种实现继承的模式,称为 "Functional inheritance",在 Crockfords "JavaScript: the good parts" 的第 5 章中有所描述 "JavaScript: the good parts"。
与使用伪经典模式相比,该模式的缺点之一是我们失去了使用 instanceof
运算符区分类型的能力。
有什么方法可以达到同样的目的吗?我们怎么知道两个对象在某种程度上是相关的,因为它们是相同的 parent/base "type"?
另外,即使它们是同一类型的后代,我们又如何判断它们本身是不同的类型?
不知道不能用instanceof
是不是很大的损失,但好像不是。
备注
对于那些不熟悉 Crockford 解释的人,您可以在以下位置查看示例:JSFiddle, taken from here。
在对象中存储一个父对象,然后
if (obj1.parentObject == obj2.parentObject) {//Do your things}
虽然inctanceof
在"Functional inheritance"("JavaScript: the good parts")中没有一定的类型和区别。
它是关于匿名函数之间的交换和关系,匿名函数生成对象,通常具有私有功能。
这些函数的逻辑层次结构是根据条件偏好设置的。
函数可以相互调用,扩展"parent"对象方法,扩展其功能。
例如,在 "functional inheritance" 中创建一个名为 "Mammal" 的 新类型 ,它看起来像:
var mammal = function (spec) {
var that = {};
that.get_.name = function () {
return spec.name;
};
that.says = function () {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({name: 'Herb'});
通过一些条件协议,我们可以接受它作为父类型(class)。
现在我们可以创建另一个匿名函数,它将负责 "Mammal" 类型(class)的子类型(subclass)。此函数将调用 "parent" 函数 mammal()
以获取具有基本功能的对象:
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.purr = function (n) {
var i, s = '';
for (i = 9; i < n; i += 1) {
if (s) {
s +=
}
s += 'r';
}
return s;
};
that.get_name = function () {
return that.says() + ' ' + spec.name + ' ' + that.says();
};
return that;
};
var myCat = cat({name: 'Henrietta'});
所以想象一下我们有这些:
mammal { giveBirth }
reptile { layEgg }
cat : mammal { purr, playWithChildren }
dog : mammal { bark }
lion : mammal { purr }
(cat
继承mammal
并实现purr()
等...)
现在假设您有一系列动物。
我想你问的是我们如何判断 animals[0]
是否是 cat
。
想知道 animals[0]
是否是 cat
的愿望来自于我们知道猫可以做某些事情的事实。而不是知道 animals[0]
是否是 cat
我们真正想知道的是 animals[0]
咕噜声。也许 animals[0].purr !== undefined
比知道它是否是 cat
更准确。这确实意味着我们需要检查每个功能,而不是我们知道实现多个功能的猫的容器概念,但它使实现更加健壮和面向未来(考虑我们是否只关心呼噜声和狮子被添加到稍后再介绍动物的种类)。
关于继承的问题,我建议我们不需要知道动物是否 mammal
我们需要知道它们是否 giveBirth
。这将再次确保我们的实施更符合未来的要求,因此当我们稍后添加 marsupial
时,我们所有关于分娩而不是下蛋的逻辑仍然有效。
instanceof
运算符并不特殊。您可以按照 Mozilla Developer Network 中的说明自行实施。有关详细信息,请参阅以下问题的已接受答案:
JavaScript inheritance and the constructor property
instanceof
运算符在 JavaScript 中的实现方式如下:
function instanceOf(object, constructor) {
while (object != null) {
if (object == constructor.prototype) { //object is instanceof constructor
return true;
} else if (typeof object == 'xml') { //workaround for XML objects
return constructor.prototype == XML.prototype;
}
object = object.__proto__; //traverse the prototype chain
}
return false; //object is not instanceof constructor
}
想要实现 instanceOf
功能继承?这也很容易做到:
var object = child({ name: "a functional object" });
alert(object.instanceOf(child)); // true
alert(object.instanceOf(base)); // true
alert(object.sayHello()); // Hello, I'm a functional object
function base(spec) {
var that = {};
that.name = spec.name;
that.constructors = [base];
that.instanceOf = instanceOf;
return that;
}
function child(spec) {
var that = base(spec);
that.sayHello = sayHello;
that.constructors.push(child);
return that;
function sayHello() {
return "Hello, I'm " + this.name;
}
}
function instanceOf(constructor) {
return this.constructors.indexOf(constructor) >= 0;
}
当然,在真正的函数式编程中根本不需要使用instanceof
。
在 JavaScript 中有一种实现继承的模式,称为 "Functional inheritance",在 Crockfords "JavaScript: the good parts" 的第 5 章中有所描述 "JavaScript: the good parts"。
与使用伪经典模式相比,该模式的缺点之一是我们失去了使用 instanceof
运算符区分类型的能力。
有什么方法可以达到同样的目的吗?我们怎么知道两个对象在某种程度上是相关的,因为它们是相同的 parent/base "type"?
另外,即使它们是同一类型的后代,我们又如何判断它们本身是不同的类型?
不知道不能用instanceof
是不是很大的损失,但好像不是。
备注
对于那些不熟悉 Crockford 解释的人,您可以在以下位置查看示例:JSFiddle, taken from here。
在对象中存储一个父对象,然后
if (obj1.parentObject == obj2.parentObject) {//Do your things}
虽然inctanceof
在"Functional inheritance"("JavaScript: the good parts")中没有一定的类型和区别。
它是关于匿名函数之间的交换和关系,匿名函数生成对象,通常具有私有功能。
这些函数的逻辑层次结构是根据条件偏好设置的。
函数可以相互调用,扩展"parent"对象方法,扩展其功能。
例如,在 "functional inheritance" 中创建一个名为 "Mammal" 的 新类型 ,它看起来像:
var mammal = function (spec) {
var that = {};
that.get_.name = function () {
return spec.name;
};
that.says = function () {
return spec.saying || '';
};
return that;
};
var myMammal = mammal({name: 'Herb'});
通过一些条件协议,我们可以接受它作为父类型(class)。
现在我们可以创建另一个匿名函数,它将负责 "Mammal" 类型(class)的子类型(subclass)。此函数将调用 "parent" 函数 mammal()
以获取具有基本功能的对象:
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.purr = function (n) {
var i, s = '';
for (i = 9; i < n; i += 1) {
if (s) {
s +=
}
s += 'r';
}
return s;
};
that.get_name = function () {
return that.says() + ' ' + spec.name + ' ' + that.says();
};
return that;
};
var myCat = cat({name: 'Henrietta'});
所以想象一下我们有这些:
mammal { giveBirth }
reptile { layEgg }
cat : mammal { purr, playWithChildren }
dog : mammal { bark }
lion : mammal { purr }
(cat
继承mammal
并实现purr()
等...)
现在假设您有一系列动物。
我想你问的是我们如何判断 animals[0]
是否是 cat
。
想知道 animals[0]
是否是 cat
的愿望来自于我们知道猫可以做某些事情的事实。而不是知道 animals[0]
是否是 cat
我们真正想知道的是 animals[0]
咕噜声。也许 animals[0].purr !== undefined
比知道它是否是 cat
更准确。这确实意味着我们需要检查每个功能,而不是我们知道实现多个功能的猫的容器概念,但它使实现更加健壮和面向未来(考虑我们是否只关心呼噜声和狮子被添加到稍后再介绍动物的种类)。
关于继承的问题,我建议我们不需要知道动物是否 mammal
我们需要知道它们是否 giveBirth
。这将再次确保我们的实施更符合未来的要求,因此当我们稍后添加 marsupial
时,我们所有关于分娩而不是下蛋的逻辑仍然有效。
instanceof
运算符并不特殊。您可以按照 Mozilla Developer Network 中的说明自行实施。有关详细信息,请参阅以下问题的已接受答案:
JavaScript inheritance and the constructor property
instanceof
运算符在 JavaScript 中的实现方式如下:
function instanceOf(object, constructor) {
while (object != null) {
if (object == constructor.prototype) { //object is instanceof constructor
return true;
} else if (typeof object == 'xml') { //workaround for XML objects
return constructor.prototype == XML.prototype;
}
object = object.__proto__; //traverse the prototype chain
}
return false; //object is not instanceof constructor
}
想要实现 instanceOf
功能继承?这也很容易做到:
var object = child({ name: "a functional object" });
alert(object.instanceOf(child)); // true
alert(object.instanceOf(base)); // true
alert(object.sayHello()); // Hello, I'm a functional object
function base(spec) {
var that = {};
that.name = spec.name;
that.constructors = [base];
that.instanceOf = instanceOf;
return that;
}
function child(spec) {
var that = base(spec);
that.sayHello = sayHello;
that.constructors.push(child);
return that;
function sayHello() {
return "Hello, I'm " + this.name;
}
}
function instanceOf(constructor) {
return this.constructors.indexOf(constructor) >= 0;
}
当然,在真正的函数式编程中根本不需要使用instanceof
。