【问题标题】:instanceof, scopes and objectsinstanceof、范围和对象
【发布时间】:2013-12-05 14:12:31
【问题描述】:
有人可以向我解释一下这种行为吗?
'use strict'
var fooFactory = function() {
function foo() {
var name = "foo object";
function getName() {
return name;
}
return {
getName: getName
}
}
function getFoo() {
return new foo;
}
return {
getFoo: getFoo,
foo: foo
}
};
var factory = new fooFactory();
var bar = factory.getFoo();
console.log("is " + bar.getName() + " instance of foo: " + (bar instanceof factory.foo));
// outputs "is foo object instance of foo: false"
我不明白,为什么 foo 对象不是我在 fooFactory 中声明的 foo 构造函数的实例。
【问题讨论】:
标签:
javascript
scope
instanceof
【解决方案1】:
您从foo 函数显式返回一个对象。该对象不是foo 的实例。因此bar 不是foo 的实例。这就是我将重写您的代码的方式:
var foo = fooFactory();
var bar = new foo;
console.log("is " + bar.getName() + " instance of foo: " +
bar instanceof factory.foo);
function fooFactory() {
return function () {
var name = "foo object";
this.getName = function () {
return name;
};
};
}
之所以会这样写,原因如下:
- 不应使用
new 调用工厂函数。只有构造函数应该用new 调用。此外,即使您确实使用new 调用fooFactory,也绝对没有区别,因为无论如何您都明确地返回了一个对象文字。事实上它会更慢。
- 与其返回一个带有构造函数的对象和另一个实例化构造函数的函数,不如简单地返回新创建的构造函数本身吗?由于您的工厂名为
fooFactory,我假设它返回foo,而不是具有foo 属性的对象。
- 如果您要创建一个函数并将其用作构造函数,则不要显式地从它返回一个对象。当您使用
new 调用函数时,JavaScript 会自动创建该函数的 prototype 的新实例,并将其绑定到函数内部的 this。只要您没有从构造函数显式返回对象,this 就会自动返回。
希望对您有所帮助。
【解决方案2】:
为了澄清 Aadit 的答案,问题在于这一行:
return {
getName: getName
}
删除它并将“getName”更改为“this.getName”,您的函数将按预期工作。
var fooFactory = function() {
function foo() {
var name = "foo object";
// changed!
this.getName = function() {
return name;
}
// no return
}
function getFoo() {
return new foo;
}
return {
getFoo: getFoo,
foo: foo
}
};
var factory = new fooFactory();
var bar = factory.getFoo();
console.log("is " + bar.getName() + " instance of foo: " + (bar instanceof factory.foo));
// true!
【解决方案3】:
删除函数 foo() 中的 return 语句
返回 {
获取名称:获取名称
}
new运算符隐式返回函数foo的子实例,
但您确实明确返回对象{ getName: getName }
{ getName: getName } is not child of function foo