如何构建类似构造函数的函数?

时间:2019-07-13 08:23:30

标签: javascript ecmascript-6

当我阅读了面向Web开发人员的专业JavaScript的第6章面向对象的编程时,它显示了一种通过构造函数创建对象的模式。

// implicit way
function Person(name) {
  this.name = name;
}

var person1 = new Person('Greg')
person1 instanceof Person
  

要创建Person的新实例,请使用new运算符。以这种方式调用构造函数实际上会导致执行以下四个步骤:

     
      
  1. 创建一个新对象。

  2.   
  3. 将构造函数的this值分配给新对象(因此指向新对象)。

  4.   
  5. 执行构造函数中的代码(向新对象添加属性)。

  6.   
  7. 返回新对象。

  8.   

这显示了如何创建对象实例的隐式方式。

我想明确地遵循它。像这样:

function Person(name) {
  var o = Object.call(this)  // step 1 and step 2
  o.name = name              // step 3
  return o                   // step 4
}

var person1 = new Person('Greg')
person1 instanceof Person // false

实际上,它不能用作构造函数模式。为什么?以及如何修改我的代码以使用显式方式创建构造函数?

https://javascript.info/constructor-new

2 个答案:

答案 0 :(得分:0)

因为Object.call(this)毫无意义,因为该函数不关心其上下文,而是返回一个普通对象。相反,您可以使用:

  Object.create(this.constructor.prototype)

答案 1 :(得分:-1)

引用的书遗漏了new所做的非常重要的细节:

  

1创建一个新对象。

真的是

1.1创建一个新对象,

1.2已在构造函数的prototype属性上原型化。

因此得出以下结果:

function Person(name) {
  var o = Object.create( Person.prototype);
  
  o.name = name              // step 3
  return o                   // step 4
}

var person1 = new Person('Greg')
console.log( person1 instanceof Person); // true
console.log( person1.constructor)         // Person

并不是您会用真实的代码完成此操作,但是出于学习目的,这是一个有趣的演示。

构造函数属性

通常,对象从其继承链继承其“构造函数”属性,并从对象的__proto属性向后搜索。

您可以创建一个名为“构造函数”的对象的本地自有属性,然后该对象将遮盖继承的值(默认情况下也可以枚举)。

如果设置函数的prototype属性的构造函数属性,则其值会更改,而该属性不会在过程中枚举:

function F() {}
console.log (F.prototype.hasOwnProperty("constructor")); // true
let f = new F();
console.log( f.constructor.name);  // F
F.prototype.constructor = Object;
let g = new F();
console.log( g.constructor.name);  // Object
F.prototype.foo = "bar";
for( var prop in F.prototype) {
   console.log( "F.prototype.%s = %s", prop, F.prototype[ prop]); // foo only
}