我在javascript中有一个简单的类:
function foo() {
this.bar = "bar";
}
var test = new foo;
console.log(foo.prototype,foo.__proto__)
/*output: foo {
constructor: function foo() {
__proto__: Object
}
,
function Empty() {}
*/
console.log(test,test.prototype,test.__proto__,test.__proto__.__proto__)
/*output: foo {
bar: "bar"
__proto__: foo
}
,
undefined
,
foo {
constructor: function foo() {
__proto__: Object
}
,
Object {
...
}
*/
我不明白:
在第一个日志中,foo.prototype
的{{1}}属性为__proto__
在第二个日志中,Object
的{{1}}属性为test.__proto__
何时使用__proto__
和何时Object
,有什么区别?
更新
在 instanceOf 部分的 John Resig's blog 中,有一些我不明白的地方:
如果我使用__proto__
Object.getPrototypeOf
prototype
,则会引发var asd = "asd";
但是
如果我使用(asd)
Object.getPrototypeOf
TypeError
,则返回var dsa = new String("dsa");
但 (dsa)
String
为什么Object.getPrototypeOf
asd.constructor.prototype == dsa.constructor.prototype
会引发错误?这是一个字符串,不是吗?
答案 0 :(得分:6)
始终使用prototype
或Object.getPrototypeOf
。
__proto__
是非标准版,已被Mozilla弃用。
John Resig对此有一个很好的blog entry。
test.prototype
未定义的原因是因为您创建了一个没有构造函数原型的新对象。以下是何时使用Object.getPrototypeOf
。
js> function foo(){}
js> typeof foo.prototype;
object
js> var f = new foo();
js> typeof f.prototype;
undefined
js> typeof Object.isPrototypeOf(f);
object
js> typeof f.constructor.prototype;
object
js> foo.prototype === Object.getPrototypeOf(f);
true
js> foo.prototype === f.constructor.prototype;
true
正如您所知,JavaScript中的继承很棘手。让我们看一个例子:
js> typeof "asdf";
string
js> typeof String("asdf");
string
字符串文字的类型为字符串。将String()
作为函数调用时也是如此。现在,由于new
运算符的行为,创建了一个新对象,其中String()
的原型作为其父对象。
js> var s = new String("asdf");
js> typeof s;
object
因为JS喜欢强迫事物,所以你可以通过以下几种方式获得字符串文字:
js> s
asdf
js> s.valueOf();
asdf
js> typeof s
object
js> typeof s.valueOf();
string
在学习JS继承时,Crockford的Prototypal Inheritance in JavaScript给了我很多帮助。
来自Mozilla的Strings页面:
可以通过创建字符串对象 调用构造函数new String()。 String对象包装了JavaScript 字符串原始数据类型 方法如下所述。全球 函数String()也可以被调用 没有新的前面创造一个 原始字符串。字符串文字 JavaScript是原始字符串。
答案 1 :(得分:5)
__proto__
是对象与其原型之间的中间对象。使用它的最大好处是,您可以完全更改对象的原型链,而无需修改实例或原型。
示例:
function F() {}
F.prototype.a = 1;
var f = new F();
f.__proto__ = { b : 2 };
"a" in f => false;
"b" in f => true;
但正如Jeremy所说,__proto__
已被弃用。唯一的用例是,如果您想为对象添加一组属性,更改其原型而不必遍历每个属性。没什么大不了的。