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 // 将上面两段代码(第6,9行)合起来,就得到下面的结论
console.log(obj.constructor.constructor === Function); // true

但是当constructor遇到prototype时,有趣的事情就发生了。

我们知道每个函数都有一个默认的属性prototype,而这个prototype的constructor(prototype.constructor)默认指向这个函数。

如下例所示:

  1.  function Person(name) {
    this.name = name;
    };
    Person.prototype.getName = function() {
    return this.name;
    };
    var p = new Person("TT"); console.log(p.constructor === Person); // true
    console.log(Person.prototype.constructor === Person); // true
    // 将上两行代码合并就得到如下结果
    console.log(p.constructor.prototype.constructor === Person); // true

当我们重新定义函数的prototype时(注意:和上例的区别,这里不是修改而是覆盖,下面的是字面量方式),constructor属性的行为就有点奇怪了,

如下示例:

  1.  function Person(name) {
    this.name = name;
    };
    Person.prototype = {
    getName: function() {
    return this.name;
    }
    };
    var p = new Person("TT");
    console.log(p.constructor === Person); // false
    console.log(Person.prototype.constructor === Person); // false
    console.log(p.constructor.prototype.constructor === Person); // false

为什么呢?

原来是因为覆盖Person.prototype时,等价于进行如下代码操作:

  1.  Person.prototype = new Object({  //Object的实例
    getName: function() {
    return this.name;
    }
    });

而constructor属性始终指向创建自身的构造函数,所以此时Person.prototype.constructor === Object,即是:

  1.  function Person(name) {
    this.name = name;
    };
    Person.prototype = { //注意是字面量方式
    getName: function() {
    return this.name;
    }
    };
    var p = new Person("TT");
    console.log(p.constructor === Object); // true
    console.log(Person.prototype.constructor === Object); // true
    console.log(p.constructor.prototype.constructor === Object); // true

怎么修正这种问题呢?方法也很简单,重新覆盖Person.prototype.constructor即可:

  1.  function Person(name) {
    this.name = name;
    };
    Person.prototype = new Object({
    getName: function() {
    return this.name;
    }
    });
    Person.prototype.constructor = Person; //重新指向Person
    var p = new Person("TT");
    console.log(p.constructor === Person); // true
    console.log(Person.prototype.constructor === Person); // true
    console.log(p.constructor.prototype.constructor === Person); // true

JavaScript对象中的constructor属性的更多相关文章

  1. JavaScript对象中的this属性

    this属性表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window: 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用. 我们还可以使用appl ...

  2. JavaScript对象中的属性(可写,可配置,可枚举,value,getter,setter)

    JavaScript中,对象包括3个特性,分别为,可扩展性,class标识符,属性. 如果对象的可扩展性为false,则不可为对象动态的添加属性.   对象包含分为存取器属性和值属性.存取属性为 {g ...

  3. JavaScript的事件对象中的特殊属性和方法(鼠标,键盘)

    鼠标操作导致的事件对象中的特殊属性和方法 鼠标事件是 Web 上面最常用的一类事件,毕竟鼠标还是最主要的定位设备.那么通过事件对象可以获取到鼠标按钮信息和屏幕坐标获取等 鼠标按钮 只有在主鼠标按钮被单 ...

  4. js对象中动态读取属性值 动态属性值 js正则表达式全局替换

    $(document).ready(function(){ var exceptionMsg = '${exception.message }'; var exceptionstr = ''; //j ...

  5. [记录] javascript 对象中使用setTimeout

    参考:Javascript对象中关于setTimeout和setInterval的this介绍 使用最后一个方法终于弄好了,简直了,在对象中使用setTimeout原来是这样的 做的是分钟倒计时,倒数 ...

  6. 在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be closed first”

    在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be ...

  7. 删除JavaScript对象中的元素

    参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...

  8. Javascript 对象的创建和属性的判定

    1. 创建对象的方法: 直接使用new 对Object对象进行操作,即对Object 对象进行实例化 <!DOCTYPE html> <html lang="en" ...

  9. Stream流用于按照对象中某一属性来对集合去重+简单数据类型集合的去重

    上次对Stream流来进行分组的文章很多人看,想看的可以来这: Stream流来进行集合分组 这次小编又带来Stream的去重,话不多数,直接上代码: 这是对简单数据类型的去重 //字符串集合进行简单 ...

随机推荐

  1. ATX 免越狱调试IOS和Android

    利用ATX配合WDA进行图形识别+自动化测试 通过使用AutomatorX,配合WebDriverAgent,可以实现在非越狱的IOS设备上更简单的进行自动化测试.同样,Android设备一样受到支持 ...

  2. 爬虫开发11.scrapy框架之CrawlSpider操作

    提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法二:基 ...

  3. OCP换考题了,052新考题及答案整理-第17题

    17.Which two statements are true about tablespaces? A) A database can contain multiple undo tablespa ...

  4. winform datagridview记录的颜色设定

    DataGridViewCellStyle属性进行如下图的设置,预览可直接看到效果

  5. jquery事件三 -- load(), ready(), resize()以及bind()事件

    例子1 ready() DOM加载完毕 load() 元素加载完毕 resize() 浏览器窗口的大小发生变化 <!DOCTYPE html> <html lang="en ...

  6. fdisk 和 parted 分区工具

    fdisk 和 parted: fdisk 是用来对 Linux 下的 MBR 分区进行操作的一款分区工具, 由于 MBR 的设计缺陷导致 MBR 不能处理大于 2TB 的硬盘, 并且主分区个数不能超 ...

  7. css图片+文字浮动(文字包围效果)

    css图片+文字浮动(文字包围效果): 在网页中,我们有时想实现这个效果,但是 <div id="test"> <img src="gdimages/0 ...

  8. Mockplus原型设计工具介绍

    一.原型设计工具简介 Mockplus (摹客)  一种快速原型设计工具 官网提供四个平台的下载,通用性很广. 二.原型设计的模板 Mockplus可以为设计者提供以下几种模板 其中在“手机”模板里, ...

  9. redis 学习笔记(一)

    redis 基本类型 String 基本操作: GET 获取存储在给定键中的值 SET 设置存储在给定键中的值 DEL 删除存储在给定键中的值 List 基本操作: LPUSH/RPUSH 从左/右推 ...

  10. HTML attribute 与 DOM property 的对比

    HTML attribute vs. DOM property 要想理解 Angular 绑定如何工作,重点是搞清 HTML attribute 和 DOM property 之间的区别. attri ...