Javascript Object.getPrototypeOf()与prototype

Javascript Object.getPrototypeOf()与prototype,javascript,Javascript,我正在学习一些JS,我希望有人能用简单的术语向我解释Object.getPrototypeOf()vs.prototype function ParentClass() {} function ChildClass() {} ChildClass.prototype = new ParentClass(); var mychild = new ChildClass(); var myparent = new ParentClass(); # .getPrototypeOf Object

我正在学习一些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
看起来你只能在构造函数上调用.prototype

还有其他区别吗

function Foo() {
    // ...
}

var a = new Foo();

Object.getPrototypeOf( a ) === Foo.prototype; // true
当通过调用
new Foo()
创建
a
时,发生的事情之一是
a
获取指向
Foo.Prototype
所指向对象的内部
[[Prototype]]
链接


如果您真的想深入学习JavaScript,我建议您阅读本系列丛书。

只有一个区别,方法获取对象的构造函数,然后返回其原型,而
prototype
属性不执行任何操作(返回自身)。(好吧,
prototype
可以是任何东西,但是如果它的对象是一个类,那么
prototype
肯定应该是一个对象。);博士
javascript中原型令人困惑的地方在于,有两种不同的东西听起来非常相似

创建新对象时,如果用于创建新对象的函数或对象具有.prototype方法,则
.prototype
引用的对象将成为新对象的prototype
newObj.\uu proto\uu

听起来很复杂。。。让我们进一步细分

A.原型属性 示例-将函数用作构造函数

当您在函数上使用
new
关键字(即,将函数用作构造函数)时,函数的.prototype将成为新的
obj.\uuuuuu proto.\uuuu

让我们首先创建一个函数并签出这个.prototype属性

function MyConstructor(){
}

console.log(MyConstructor.prototype)  // {}
等等<代码>MyConstructor.prototype/{}-发生了什么神奇的事情吗?这个空对象
{}
来自哪里

这里有两件事:

  • 无论何时声明函数,Javascript都会自动创建一个.prototype对象

  • 此对象不是空的。它实际上有一个指向创建对象的函数(对象的“构造函数”)的属性。让我们来看看:

  • console.log(MyConstructor.prototype.constructor);//[功能: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
    
    显然,我们可以从上面的代码中看到MyConstructor和MyConstructor.prototype是两个独立的实体

    B.对象的原型 对象的原型(not.prototype-参见上面的A)是javascript用来查找和解析对象中不存在的方法的(稍后将对此进行详细介绍)

    从上面继续,当我们从具有.prototype属性的函数或对象创建对象时,新创建的对象将有它的
    对象。\uuuu proto\uuu
    引用此.prototype对象

    对象的原型可以通过

    Object.getPrototypeOf(obj)

    还是不推荐的

    obj.\uuuu proto\uuuuu

    示例-将函数用作构造函数

    让我们使用函数MyConstructor作为构造函数创建新对象

    function MyConstructor(){
    }
    
    var obj = new MyConstructor()
    
    console.log(Object.getPrototypeOf(obj));  // {}
    
    以下是三件相关的事情:

    • MyConstructor(函数)
    • obj(从MyConstructor创建的对象)
    • obj.\uuuu proto\uuuu
      -->MyConstructor.prototype
    因此,
    obj.\uuuu proto\uuuu
    MyConstructor.prototype
    。这是证据:

    MyConstructor.prototype === Object.getPrototypeOf(obj)  // true
    
    让我们向MyConstructor添加一个方法

    function MyConstructor(){
      this.func1 = function(){
        console.log("this is func1");
      };
    }
    
    var obj = new MyConstructor();
    
    obj.func1();  // this is func1
    
    从上面可以看出,您可以调用构造函数中声明的方法。事实上,如果我们仔细看一下,我们声明的方法func1实际上是obj的一部分,因为javascript创建对象的方式

    console.log(obj); // MyConstructor { func1: [Function] }
    
    我们还可以通过将方法添加到原型中来添加obj可以使用的方法。e、 g

    MyConstructor.prototype.func2 = function(){
      console.log("this is func2");
    };
    
    obj.func2(); // this is func2
    
    MyConstructor和MyConstructor.prototype方法将可用于使用此设置使用MyConstructor创建的所有对象


    有用的参考资料

    Object.getPrototypeOf()
    vs
    .prototype
    • Prototype
      :javascript中的每个对象都有一个Prototype。这只是它“继承”属性和方法的另一个对象。这个概念称为原型继承,是javascript中唯一存在的继承形式。javascript中的
      关键字之类的结构仅仅是建立在这个原型继承系统之上的语法糖

      每个函数都有一个
      原型
      对象属性。当此函数被用作带有
      new
      关键字的构造函数时,新创建的对象将从此
      prototype
      对象继承

    • Object.getPrototypeOf()
      :是返回此原型对象引用的函数。我们传入一个对象作为参数,它将返回原型对象引用

    例子:
    功能狗(名称){
    this.name=名称;
    }
    //我们可以在Dog构造函数的原型上添加属性
    Dog.prototype.bark=函数(){console.log('woof');};
    let dog=新狗(‘fluffie’);
    //我们新创造的狗现在可以通过原型链使用这种吠叫方法
    狗吠();
    //使用Object.getPrototypeOf方法返回Dog prototype对象
    log(Object.getPrototypeOf(dog))原型是JavaScript对象相互继承特性的机制

    Object.getPrototypeOf
    -返回给定对象的原型

    下面的代码定义了一个构造函数,可用于
    MyConstructor.prototype.func2 = function(){
      console.log("this is func2");
    };
    
    obj.func2(); // this is func2
    
    function Cat(name) {
        this.name = name;
    }
    
    Cat.prototype.meow = function (sound) {
        console.log(`Meow ${sound}`);
    };
    
    let cat = new Cat("Garfield");
    
    // This is a Cat object
    > cat
    Cat {name: "Garfield"}
    
    > cat.prototype // notice that this object does not have the prototype property
    undefined
    
    // this is the constructor function
    > Cat
    ƒ Cat(name) {
        this.name = name;
    }
    
    // this is the prototype property of a constructor
    > Cat.prototype
    {meow: ƒ, constructor: ƒ}
    meow: ƒ (sound)
    constructor: ƒ Cat(name)
    __proto__: Object
    
    // this is true as previously stated
    > Object.getPrototypeOf(Cat) == Function.prototype 
    true
    
    // this is true since the property prototype of a constructor is the
    // prototype that objects created from it will have
    > Object.getPrototypeOf(cat) == Cat.prototype
    true
    
    // Finally the prototype of the prototype property of a constructor
    // is the same as Object.prototype
    > Object.getPrototypeOf(Cat.prototype) == Object.prototype
    true
    
    class Cat {
        constructor(name) {
            this.name = name;
        }
    
        meow(sound) {
            console.log(`Meow ${this.sound}`);
        }
    }
    
    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()
    
    function MyConstructor() {}
    MyConstructor.prototype = "foo" // make objects inherit from... a string?
    var obj = new MyConstructor()
    Object.getPrototypeOf(obj) === MyConstructor.prototype // false!