当我阅读了面向Web开发人员的专业JavaScript的第6章面向对象的编程时,它显示了一种通过构造函数创建对象的模式。
// implicit way
function Person(name) {
this.name = name;
}
var person1 = new Person('Greg')
person1 instanceof Person
要创建Person的新实例,请使用new运算符。以这种方式调用构造函数实际上会导致执行以下四个步骤:
创建一个新对象。
将构造函数的this值分配给新对象(因此指向新对象)。
执行构造函数中的代码(向新对象添加属性)。
返回新对象。
这显示了如何创建对象实例的隐式方式。
我想明确地遵循它。像这样:
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
实际上,它不能用作构造函数模式。为什么?以及如何修改我的代码以使用显式方式创建构造函数?
答案 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
}