JavaScript:构造函数与原型

Tay*_*ton 7 javascript

这已经得到了回答,但我想证实我的理解.在这段代码中:

var somePrototype = {
  speak: function() {
    console.log("I was made with a prototype");
  }
}

function someConstructor() {
  this.speak = function() {
    console.log("I was made with a constructor");
  }
}

var obj1 = Object.create(somePrototype);
var obj2 = new someConstructor();

obj1.speak();
obj2.speak();
Run Code Online (Sandbox Code Playgroud)

他们从根本上做同样的事情,对吗?唯一的区别是它function someConstructor()被提升,这意味着我可以在它被定义之前调用它的新实例,如果需要的话,var somePrototype只能在它被定义之后被调用.除此之外,没有区别?

Dmi*_*tin 8

两种方法(使用Object.create()和构造函数调用)之间的差异是:

创作:

  • Object.create(somePrototype)创建一个新的对象,使其成为somePrototype原型;
  • new someConstructor()使用构造函数调用创建对象.原型obj2是一个简单的对象:new Object()

属性继承:

  • obj1继承属性speak,这是一个函数.如果此属性在somePrototype对象中发生更改,则会影响Object.create(somePrototype)用于继承它的任何对象.
    Object.keys(obj1)将返回[],因为该对象没有自己的属性.
  • obj2包含自己的财产speak.在单个实例上修改此属性不会影响使用创建的任何其他实例new someConstructor().
    Object.keys(obj2)['speak']作为其列出的财产返回.

构造函数:

  • obj1.constructor === Objecttrue
  • obj2.constructor === someConstructortrue

吊装:

  • someConstructor被提升到它创建的范围的顶部.所以它可以在函数声明之前使用.
  • 并且肯定somePrototype没有使用对象文字提升,因此应在设置值后使用.

查看这篇关于constructor财产的有趣帖子.


Poi*_*nty 6

Object.create()调用创建一个对象并为其提供您请求的原型.该new调用创建一个由该构造函数直接修饰的对象.

区别在于构造函数创建的对象有一个自己的属性,其值是带有的函数console.log().该Object.create()调用创建一个从原型对象继承类似函数的对象.

如果您将第一个对象传递给Object.keys(),则不会看到"speak"属性; 如果你传递了第二个对象,你会的.