Function object prototype
1 2 3 4 5 6 7
| function funcObj() { }
funcObj.prototype.greet ="hello";
console.log(funcObj.greet) // undefined ???
console.log(funcObj.prototype.greet) // hello
var obj = new funcObj();
console.log(obj.greet); // hello |
根据我对原型的理解。如果您访问一个对象的成员,当该对象中不可用时,它将从原型对象中获取该成员。
我的问题是:
因为javascript中的函数是对象,所以funcObj.greet->未定义,而obj.greet->hello?
- 只有构造函数具有.prototype属性,当使用new调用它们时使用该属性。所有对象都有原型,但这不是属性。
原型只不过是实例从中继承属性的对象。
因此,funcObj是另一个原型(Function中的一个)的实例,它继承了所有的属性。另外,它本身也有一个prototype,您可以在上面绑定您想要的任何东西,并且一旦您调用原型来构造funcObj的新实例(即,当您与new密钥一起调用它时,作为new funcObj()),原型将被使用。
正因为如此,funcObj没有一个名为greet的成员,而它的实例有这个成员,这是完全正常的。
- 因此,每个函数对象本身都是来自函数构造函数的实例。所以,如果我将我的属性添加到function.prototype中,它将由所有函数实例共享,对吗?
- 或多或少。实际上,函数绑定到的范围是不同的,它是当前的这个引用。
与class Foo本身与new Foo的类型不同,Foo没有理由拥有您分配给Foo.prototype的任何属性。原因有点不同,但是把它考虑到另一种语言,比如Java,很明显,你想做的只是不起作用:
1 2 3 4 5 6 7 8 9 10 11 12
| class Foo {
public String bar ="analogous to Foo.prototype.bar which is a property of Foo instances";
}
class Baz {
String thisMethodShouldAndWillFail() {
return Foo.bar;
}
String thisIsWhatShouldAndWillWork() {
return (new Foo()).bar;
}
} |
在JavaScript中,您需要纠正原型是什么以及它如何与对象和构造函数相关的想法,否则您将不断遇到问题。Foo有原型,但原型不是Foo.prototype。Foo本身没有什么特性是它的原型。Foo的原型是由其构造函数Foo决定的;这样做更有意义,因为在构造Foo.prototype之后,可以将任何旧值赋给它,它通过将Foo转换为一个未初始化的类的实例来破坏它。
如果构造函数Foo作为它定义的类的实例,它也同样没有任何意义;它没有被自己初始化,因此不能安全地假定它将实现它的实例预期的行为。Foo是Function的一个实例,这是有意义的,因为它可以被调用。因此,Foo的原型是Function.prototype,而不是Foo.prototype。
Foo与其原型之间的关系是在您调用foo = new Foo时建立的。由于预期构造函数Foo的主体将初始化实例,因此这是唯一一次向Foo提供有意义的原型。原型为对象提供了它的公共行为,构造函数初始化对象,以便这些行为按预期工作。通过new Foo建造时,分配给Foo的原型不是Foo.prototype以外的原型;这是在执行Foo之前为了方便和保证它不可能被弄乱。之后,如果不明确地通过Foo,就无法访问Foo的原型。
因为函数与实例是不同的对象。
将属性放在一个对象上不会影响任何其他对象,甚至不会影响该对象或原型所属的函数。