我正在学习一些JS,我希望有人可以用简单的术语向我解释Object.getPrototypeOf()vs 之间的区别.prototype
function ParentClass() {}
function ChildClass() {}
ChildClass.prototype = new ParentClass();
var mychild = new ChildClass();
var myparent = new ParentClass();
# .getPrototypeOf
Object.getPrototypeOf(ChildClass.prototype) // ParentClass {}
Object.getPrototypeOf(mychild) // ParentClass {}
Object.getPrototypeOf(ParentClass.prototype) // {}
Object.getPrototypeOf(myparent) // ParentClass {}
# .prototype
ParentClass.prototype // ParentClass {}
myparent.prototype // undefined
ChildClass.prototype // ParentClass {}
mychild.prototype // undefined
Run Code Online (Sandbox Code Playgroud)
所以看起来你只能在构造函数上调用.prototype?
还有其他差异吗?
luk*_*aus 36
function MyConstructor() {}
var obj = new MyConstructor()
Object.getPrototypeOf(obj) === obj.prototype // false
Object.getPrototypeOf(obj) === MyConstructor.prototype // true
MyConstructor.prototype // MyConstructor {}
obj.prototype // undefined
MyConstructor.prototype.constructor === MyConstructor // true
Object.getPrototypeOf(MyConstructor) === Function.prototype // true
Run Code Online (Sandbox Code Playgroud)
关于javascript中原型的令人困惑的部分是有两种不同的东西听起来非常相似.
创建新对象时,如果用于创建新对象的函数或对象具有.prototype方法,则引用的对象.prototype将成为新对象的原型newObj.__proto__.
听起来很复杂......让我们进一步分解.
示例 - 使用函数作为构造函数
在new函数上使用关键字时(即使用函数作为构造函数),函数的.prototype将成为新函数obj.__proto__.
让我们首先创建一个函数并检查这个.prototype属性
function MyConstructor(){
}
console.log(MyConstructor.prototype) // {}
Run Code Online (Sandbox Code Playgroud)
等等...... MyConstructor.prototype // {}- 做了神奇的事情吗?这个空物体{}来自哪里?
这里有2件事:
每当您声明一个函数时,Javascript都会自动创建一个.prototype对象 - 自动生成.
该对象不为空.它实际上有一个属性,指向创建对象的函数(对象的'构造函数').让我们来看看:
console.log(MyConstructor.prototype.constructor); // [Function: MyConstructor]
MyConstructor.prototype.constructor === MyConstructor // true
因此,对于函数,会自动创建.prototype属性及其关联对象.
仍然困惑?让我们在那里添加一些方法,以便更容易看到发生了什么......
function MyConstructor(){
}
MyConstructor.prototype.func2 = function(){
};
console.log(MyConstructor); // [Function: MyConstructor]
console.log(MyConstructor.prototype); // MyConstructor { func2: [Function] }
MyConstructor.func2(); // TypeError: MyConstructor.func2 is not a function
Run Code Online (Sandbox Code Playgroud)
显然,我们可以从上面的代码中看到MyConstructor和MyConstructor.prototype是2个独立的实体.
对象的原型(不是.prototype - 参见上面的A.)是javascript用于查找和解析对象中尚未存在的方法的内容(稍后将详细介绍).
从上面继续,当我们从具有.prototype属性的函数或对象创建对象时,新创建的对象将使它object.__proto__引用此.prototype对象.
可以通过访问对象的原型
Object.getPrototypeOf(obj)
或者弃用了
obj.__proto__
示例 - 使用函数作为构造函数
让我们使用函数MyConstructor作为构造函数创建一个新对象.
function MyConstructor(){
}
var obj = new MyConstructor()
console.log(Object.getPrototypeOf(obj)); // {}
Run Code Online (Sandbox Code Playgroud)
以下是三个相关的事情:
obj.__proto__ - > MyConstructor.prototype所以obj.__proto__是MyConstructor.prototype.这是证明:
MyConstructor.prototype === Object.getPrototypeOf(obj) // true
Run Code Online (Sandbox Code Playgroud)
让我们为MyConstructor添加一个方法
function MyConstructor(){
this.func1 = function(){
console.log("this is func1");
};
}
var obj = new MyConstructor();
obj.func1(); // this is func1
Run Code Online (Sandbox Code Playgroud)
从上面你可以看到你可以调用在构造函数中声明的方法.事实上,如果我们看一下,由于javascript创建对象的方式,我们声明的方法func1实际上是obj的一部分.
console.log(obj); // MyConstructor { func1: [Function] }
Run Code Online (Sandbox Code Playgroud)
我们还可以通过将方法添加到原型中来添加obj可以使用的方法.例如
MyConstructor.prototype.func2 = function(){
console.log("this is func2");
};
obj.func2(); // this is func2
Run Code Online (Sandbox Code Playgroud)
MyConstructor和MyConstructor.prototype方法将可用于使用此设置使用MyConstructor创建的所有对象.
有用的参考资料
@lukeaus 的回答非常好。对我来说,最重要的几点是:
function MyConstructor() {} // automatically creates MyConstructor.prototype
// You can add methods to MyConstructor.prototype for objects to "inherit"
MyConstructor.prototype.foo = function() { console.log("do foo") }
// Or even reassign .prototype
// MyConstructor.prototype = { foo: function() { console.log("more foo?") } }
var obj = new MyConstructor()
Object.getPrototypeOf(obj) === MyConstructor.prototype // true
obj.foo()
Run Code Online (Sandbox Code Playgroud)
所以obj的原型就是MyConstructor.prototype。MyConstructor 的原型是什么?好吧,每个函数都“继承”自 Function,所以Object.getPrototypeOf(MyConstructor) === Function.prototype
作为旁注,如果你将 .prototype 分配给一些愚蠢的东西,事情就会变得很奇怪:
function MyConstructor() {}
MyConstructor.prototype = "foo" // make objects inherit from... a string?
var obj = new MyConstructor()
Object.getPrototypeOf(obj) === MyConstructor.prototype // false!
Run Code Online (Sandbox Code Playgroud)
它们肯定是不同的,但它们非常相似,因为它们都只是检索原型。您可以使用Object.getPrototypeOf()和.prototype来获得完全相同的结果:
function Plant(type, size) {\n this.type = type,\n this.size = size\n};\n\nlet plant1 = new Plant("grass", "small")\n\nconsole.log(Plant.prototype === Object.getPrototypeOf(plant1)) // returns true\nRun Code Online (Sandbox Code Playgroud)\n区别在于,.prototype将获取指定构造函数实例的原型,而Object.getPrototypeOf()将获取括号 \xe2\x80\x94 内指定的对象的原型,无论该对象是构造函数还是(据我所知)任何其他目的。
换句话说,当您这样做时MyConstructor.prototype,您不会获得 的原型,而是获得 的实例MyConstructor的原型。MyConstructor如果你想要 的原型MyConstructor,你可以这样做
Object.getPrototypeOf(MyConstructor) // preferred, or \nMyConstructor.__proto__ // bad because MDN says so\nRun Code Online (Sandbox Code Playgroud)\n免责声明:总体而言,我对 JS 和编程还是或多或少的新手。这个解释只是我自己尝试理解这个主题的结果。
\n| 归档时间: |
|
| 查看次数: |
5805 次 |
| 最近记录: |