JavaScript原型属性”

时间:2019-09-30 01:16:46

标签: javascript prototype-chain

我正在遵循javascript中有关“函数构造函数”和“原型链”的逻辑,但是我试图从原型的精确度角度来解决原型链的重要性。

函数Constructor对创建对象很有用,对吗?因此,在使用“函数构造器”创建对象时,该对象是否尚未拥有指向链中较高位置的“全局对象”的指针? ...如果是的话,为什么还要包含这个“原型属性”呢?要么... 原型属性是否实际上“实例化”了将功能对象链接到全局对象的继承链。

如果prototype属性未实例化对象的本地上下文和全局上下文之间的链接,为什么要完全包含它?如果我从函数构造函数的属性列表中省略了prototype属性,那将会发生什么变化?

我只需要在原型属性的目的后面有一个清晰明了的理由,就这一点而言,这是有道理的,但就其对继承链的贡献而言仍然没有道理。

感谢阅读。

2 个答案:

答案 0 :(得分:0)

如果执行以下代码行

function Dog(){
    this.constBreed = "Pug";
}
Dog.prototype.breed = "Bull";

var newDog = new Dog();

console.log(newDog);

日志将为您提供以下结果

Dog {constBreed: "Pug"}
    constBreed: "Pug"
    __proto__:
        breed: "Bull"
        constructor: ƒ Dog()
        __proto__: Object

此处,构造函数变量“ constBreed”直接附加到“ newDog”对象,原型属性“ breed”进入 proto 链。

这非常有用,因为我们可以通过Dog()函数创建多个新的Dog变量,并通过更改Dog()函数本身的protopye.breed一次更改它们的种类。

对于构造函数变量“ constBreed”,它只是为通过Dog()函数创建的每个新对象复制并重新初始化。

答案 1 :(得分:0)

  

我只需要在原型属性的目的后面有一个清晰明了的理由,就这一点而言,这是有道理的,但就其对继承链的贡献而言仍然没有道理。

让我们以下面的代码为例:

function Foo(prop) {
  this.fooProperty = prop
}

Foo.prototype.greetFoo = function() {
  console.log('hi from foo')
}

function Bar(prop1, prop2) {
  Foo.call(this, ...arguments)
  this.barProperty = prop2
}

// Replace the default Bar.prototype object with one that links to Foo.prototype
Bar.prototype = Object.create(Foo.prototype)
Bar.prototype.greetBar = function() {
  console.log('hi from bar')
}

const barInstance1 = new Bar('baz', 'rar')
const barInstance2 = new Bar('qum', 'yas')

barInstance1.greetFoo()
barInstance2.greetFoo()
barInstance1.greetBar()
barInstance2.greetBar()

上面将产生以下原型链:

Object.prototype <- Foo.prototype <- Bar.prototype <- barInstance1
                    > greetFoo()     > greetBar()     > fooProperty = 'baz'
                                                      > barProperty = 'rar'
                                                   <- barInstance2
                                                      > fooProperty = 'qum'
                                                      > barProperty = 'yas'

在传统的OOP中,类是“蓝图”,而实例是根据实例类的继承层次结构的“展平/合并”蓝图创建的对象。 JS“继承”的工作原理与此不同。 JS继承使用链接的 live 对象而不是蓝图的层次结构工作。

当您访问实例上没有的实例(例如greetFoo()greetBar())时,JS将递归地查找链以找到它。该链可能涉及其他具有更多功能的原型。这就是JS“代码共享”的工作方式。

在上面的示例中,

  • barInstance1barInstance2链接到Bar.prototype。这两个实例现在都有greetBar()
  • Bar.prototype也链接到Foo.prototype,这意味着实例也将获得greetFoo
  • 最后,Foo.prototype链接到内置的Object.prototype,使所有实例都可以访问所有本机对象方法,例如hasOwnPropertytoString()等。
相关问题