function New(f){
return function(){
var o = {'__proto__': f.prototype};
f.apply(o, arguments);
return o;
}
}
function Person(name, age){
this.name = name;
this.age = age;
}
var p = New(Person)('xl', 24);

在一段javascript基础学习视频中,老师大胆想象了一下new方法创造实例对象的原理。

其中一个关键点,让对象的__proto__属性指向任何一个构造函数:{'__proto__': f.prototype}

这个我就蛮好奇的,直接这样,然后以下两段都成立了。

p instanceof Person   // true
p.constructor === Person // true

以上说明,这个隐藏的属性__proto__的指向一旦建立,那么p实例的constructor就自动指向了Person构造器(此理解是错的)。

2018-05-03:今天继续了解原型链时,发现我这里理解错了。其实p实例没有生成指向Person构造器的constructor属性,因为测试发现p.hasOwnProperty('constructor')结果是false。发现p.constructor有值,并指向Person,是因为p在自己上面找不到constructor时,沿着原型找到了Person原型的constructor属性,所以下图才是对的。

但是我还是好奇为什么。

之前我一直以为instanceof 是否成立还和constructor有关系。

而实际上是,{'__proto__': f.prototype}这个直接的导致了constructor关系(上图绿线)的建立。当我试图把constructor的两个关系重新指向时,

p.constructor = {other: 1};
Person.prototype.constructor = {other: 2}; p instanceof Person // true

p仍然是Person的实例,所以instanceof和constructor无关。而当我试图改变Person的prototype的指向之后,终于变了

Person.prototype = {other: 3}

p instanceof Person   // false

另外我尝试了一下,在改变Person.prototype指向之前,让其他任何函数的prototype都指向Person.prototype,则

function Person2(){}
Person2.prototype = Person.prototype p instanceof Person // true
p instanceof Person2 // true

p可以是多个构造函数的实例。

试验之后的结论是:

instanceof 与constructor属性无必然关系,只要对象的隐藏属性__proto__指向任何构造器的prototype属性,那么对象都会是该构造器的实例;对象也可以是多个构造器的实例。

修改:

结论改为

instanceof 与constructor属性无必然关系,只要对象的隐藏属性__proto__,或者对象的__proto__的__proto__,或者对象的__proto__的__proto__的__proto__..........指向任何构造器的prototype属性,那么对象都会是该构造器的实例;对象也可以是多个构造器的实例。

夯实JavaScript基础之prototype, __proto__, instanceof的更多相关文章

  1. 深入理解JavaScript原型:prototype,__proto__和constructor

    JavaScript语言的原型是前端开发者必须掌握的要点之一,但在使用原型时往往只关注了语法,其深层的原理并未理解透彻.本文结合笔者开发工作中遇到的问题详细讲解JavaScript原型的几个关键概念, ...

  2. JavaScript:Function/Object/prototype/__proto__

    console.log(Object.__proto__===Function.prototype); //true console.log(Object.prototype.__proto__); ...

  3. js prototype __proto__ instanceof constructor

    JS中有两个特殊的对象:Object与Function,它们都是构造函数,用于生成对象. Object.prototype是所有对象的祖先,Function.prototype是所有函数的原型,包括构 ...

  4. 你真的懂JavaScript基础类型吗

    夯实Javascript基础. 基本类型有六种: null,undefined,boolean,number,string,symbol. 基本类型的值是保存在栈内存中的简单数据段 基础类型特性 基础 ...

  5. JavaScript中的prototype和__proto__细致解析

    最近在学js,体会了一点点它的灵活性.对于初学者的我,总是被它的灵活感到晕头转向,最近发现了一点东西想与大家分享. JavaScript中的prototype和_proto_: 我们先了解一点js中的 ...

  6. 15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  7. javascript--15条规则解析JavaScript对象布局(__proto__、prototype、constructor)

    大家都说JavaScript的属性多,记不过来,各种结构复杂不易了解.确实JS是一门入门快提高难的语言,但是也有其他办法可以辅助记忆.下面就来讨论一下JS的一大难点-对象布局,究竟设计JS这门语言的人 ...

  8. 对于JavaScript对象的prototype和__proto__的理解

    一.Object和Function的关系: 刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象.瞬间觉 ...

  9. javascript prototype __proto__区别

    An Object's __proto__ property references the same object as its internal [[Prototype]] (often refer ...

随机推荐

  1. es7 async 前置依赖

    https://stackoverflow.com/questions/33527653/babel-6-regeneratorruntime-is-not-defined 移动端 px2rem-lo ...

  2. MySQL中的触发器insert、update

    以下为MySQL 触发器insert 的3个示例演示(update类似) delimiter // create trigger InsertUser before insert on user fo ...

  3. 从一个url地址到最终页面渲染完成,发生了什么?

    从一个url地址到最终页面渲染完成,发生了什么? 1.DNS 解析 : 将域名地址解析为IP地址 浏览器DNS缓存 系统DNS缓存 路由器DNS缓存 网络运营商DNS缓存 递归搜索: www.baid ...

  4. IDEA Caused by: java.lang.OutOfMemoryError: PermGen space

    错误:OutOfMemoryError: PermGen space 非堆溢出(永久保存区域溢出) 解决方法: 在Run/Debug configuration 的你要运行行的tomcat里面的 vm ...

  5. stat - 打印信息节点(inode)内容

    SYNOPSIS(总览) stat filename [filenames ... ] DESCRIPTION(描述) stat 打印出一个信息节点的内容,它们显示为对人可读的格式的stat(2). ...

  6. VUE.JS 环境配置

    首先安装   node.js 网址 https://nodejs.org/en/ 选择版本 点击直接安装OK  (不用安装到系统盘) 然后cmd 命令框 输入 npm -version (查看安装版本 ...

  7. rabbitmq AmqpClient 使用Topic 交换机投递与接收消息,C++代码示例

    // strUri = "amqp://guest:guest@192.168.30.11:8820/test" // strUri = "amqp://[帐户名]:[密 ...

  8. 封装加减乘除函数 解决JS 浮点数计算 Bug

    计算机内部的信息都是由二进制方式表示的,即0和1组成的各种编码,但由于某些浮点数没办法用二进制准确的表示出来,也就带来了一系列精度问题.当然这也不是JS独有的问题. 例如, 我们在用JS做浮点运算会遇 ...

  9. java中文乱码转换

    String str=URLDecoder.decode(String, "UTF-8")

  10. Mysql学习笔记(001)-常见命令

    常见命令 SHOW DATABASES; /* use test; create database myemployees; use myemployees; create table employe ...