constructor属性始终指向创建当前对象的构造函数。比如下面例子:
- // 等价于 var foo = new Array(1, 56, 34, 12);
- var arr = [1, 56, 34, 12];
- console.log(arr.constructor === Array); // true
- // 等价于 var foo = new Function();
- var Foo = function() { };
- console.log(Foo.constructor === Function); // true
- // 由构造函数实例化一个obj对象
- var obj = new Foo();
- console.log(obj.constructor === Foo); // true
- // 将上面两段代码合起来,就得到下面的结论
- console.log(obj.constructor.constructor === Function); //
true
复制代码
但是当constructor遇到prototype时,有趣的事情就发生了。
我们知道每个函数都有一个默认的属性prototype,而这个prototype的constructor默认指向这个函数。如下例所示:
- function Person(name) {
- this.name = name;
- };
- Person.prototype.getName = function() {
- return this.name;
- };
- var p = new Person("ZhangSan");
- console.log(p.constructor === Person); // true
- console.log(Person.prototype.constructor === Person); // true
- // 将上两行代码合并就得到如下结果
- console.log(p.constructor.prototype.constructor === Person); //
true
复制代码
当时当我们重新定义函数的prototype时(注意:和上例的区别,这里不是修改而是覆盖),constructor属性的行为就有点奇怪了,如下示例:
- function Person(name) {
- this.name = name;
- };
- Person.prototype = {
- getName: function() {
- return this.name;
- }
- };
- var p = new Person("ZhangSan");
- console.log(p.constructor === Person); // false
- console.log(Person.prototype.constructor === Person); // false
- console.log(p.constructor.prototype.constructor === Person); //
false
为什么呢?
原来是因为覆盖Person.prototype时,等价于进行如下代码操作:
- Person.prototype = new Object({
- getName: function() {
- return this.name;
- }
- });
而constructor属性始终指向创建自身的构造函数,所以此时Person.prototype.constructor
=== Object,即是:
- function Person(name) {
- this.name = name;
- };
- Person.prototype = {
- getName: function() {
- return this.name;
- }
- };
- var p = new Person("ZhangSan");
- console.log(p.constructor === Object); // true
- console.log(Person.prototype.constructor === Object); // true
- console.log(p.constructor.prototype.constructor === Object); //
true
怎么修正这种问题
呢?方法也很简单,重新覆盖Person.prototype.constructor即可:
- function Person(name) {
- this.name = name;
- };
- Person.prototype = new Object({
- getName: function() {
- return this.name;
- }
- });
- Person.prototype.constructor = Person;
- var p = new Person("ZhangSan");
- console.log(p.constructor === Person); // true
- console.log(Person.prototype.constructor === Person); // true
- console.log(p.constructor.prototype.constructor === Person); //
true
|
相关推荐
要修正这一问题,需要在覆盖prototype属性后,显式地重新设置constructor属性: ```javascript Person.prototype = { constructor: Person, // 重新设置constructor属性指向Person getName: function() { return...
// prototype对象有一个constructor属性,指向BB这个函数。 console.log(b.constructor === BB.prototype.constructor); // true ``` 这段代码说明了`constructor`属性的基本作用: 1. **原型链上的引用**:`...
为了解决这个问题,我们可以在子类构造函数中明确设置其 prototype 对象的 constructor 属性: ```javascript function Employee(name, age) { Person.call(this, name, age); } Employee.prototype = Object....
2. 如何使用constructor属性: 一旦创建了对象实例,我们就可以访问其constructor属性来获取创建该对象的构造函数。在示例中,通过`bool.constructor`就能够获取到Boolean的构造函数。 3. 输出constructor属性: ...
在JavaScript中,类和继承是面向对象编程的重要概念。JavaScript是一种动态类型的语言,它没有像Java或C++那样的传统类,而是使用函数作为构造器来模拟类的行为,并通过原型链实现继承。本文将深入探讨JavaScript中...
除了传统的原型链继承,JavaScript还支持其他继承模式,如组合继承(组合使用构造函数和原型链)、寄生继承(通过创建父类副本改进继承)、原型式继承(使用`Object.create()`)、寄生组合式继承(被认为是最有效的...
总结一下,JavaScript的类继承是通过构造函数、原型链和实例化来实现的。`this.callParent`方法(虽然不是原生JavaScript特性)提供了一种优雅的方式,允许我们在子类中调用父类的方法,从而保持代码的整洁和可维护...
prototype 属性的作用: 利用prototype 属性提供对象的类的一组基本功能。对象的新实例“继承”赋予该对象原型的操作。 prototype 属性的功能: 所有JavaScript 内部对象都有只读的prototype 属性。可以为内部对象的...
通过`class`和`extends`关键字,子类可以继承父类的所有属性和方法,而且父类的静态属性和方法也能被继承。这提供了更清晰的语法,但底层仍然是原型链机制。 6. 寄生继承(Parasitic Inheritance) 寄生继承的思想...
在控件开发中,我们通常会创建一个基础控件类,然后让其他特定类型的控件继承这个基础类,以便共享相同的属性和行为。 例如,我们可以定义一个基础的`Control`类,包含通用的属性如位置、大小、样式等,以及通用的...
继承在ExtJS中的实现主要基于`Ext.extend()`方法,这个方法是ExtJS提供的一个静态方法,它允许一个类(子类)继承另一个类(父类)的所有属性和方法。通过`Ext.extend()`,我们可以定义新的类,同时保留和扩展已存在...
总结来说,constructor 属性和 prototype 属性在 JavaScript 中非常关键,它们共同构成了 JavaScript 原型继承的基础。理解这两个属性的工作原理对于掌握 JavaScript 面向对象编程及其继承机制至关重要。
本文将深入探讨JavaScript继承的实现方式,以及其中的问题和解决方案。 首先,我们来看混合方式的实现,这种方式结合了原型链和对象冒充。在JavaScript中,构造函数是用于创建特定类型对象的函数。例如,`Employee`...
// 修复constructor属性,使其指向Zhangsan构造函数 ``` 在这个例子中,我们通过`Object.create`方法创建了一个新的原型对象,这个新对象的`__proto__`指向Person的原型。然后,我们用`call`方法在Zhangsan的实例...
除了基本的函数构造和实例创建,`constructor`属性在JavaScript的继承机制中也扮演着重要角色。例如,淘宝的Kissy框架中,就有类似的继承实现方式。其中有一个`O`函数,用于实现原型继承: ```javascript O = ...
通过以上分析,我们了解到JavaScript中基于原型的继承机制,它与传统基于类的继承有所不同,但仍然提供了实现代码复用和创建复杂对象层次结构的能力。掌握原型继承对于深入理解JavaScript对象模型和设计模式至关重要...
JavaScript的继承基于原型链(prototype chain),它允许一个对象可以继承另一个对象的属性和方法。通过`__proto__`或`Object.getPrototypeOf()`可以访问到父对象,而`Object.create()`则用于创建一个新的对象并设置...
JavaScript继承机制探讨及其应用 JavaScript是一门弱类型语言,具有函数式编程和面向对象编程的特点。随着近几年JavaScript生态圈的发展和成熟,项目的编码量和复杂度也在呈几何级数增长。JavaScript面向对象编程中...