资讯专栏INFORMATION COLUMN

图解javascript原型&原型链

sutaking / 773人阅读

我们在学习javascript时,经常会听到“万物皆对象”,但是呢,其实万物皆对象的对象也有区别。分为普通对象和函数对象。
1.对象分为函数对象和普通对象
    通过new Function()创建的对象都是函数对象,其他的都是普通对象。

2.构造函数
而提到new关键字,我们不得不提到构造函数。构造函数又分为自定义构造函数及native构造函数(即构造器)
2.1 自定义构造函数

 function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
    }
    var miya = new Person("miya",18,"engineer"); //miya是构造函数Person的实例;

而实例的构造函数属性(constructor) 都指向构造函数
    即:miya.constuctor = Person 
    
2.2 构造器 
    js内置的构造器包括Number,Boolean,String,Object,Function,Array,RegExp,Error,Date等
同样的,我们的构造器的实例也有一个constuctor指向它的构造器
   

    let miya= new Array()
    miya.constuctor ==Array;

通过以上的分析,我们可以得到以下这张图    

这里扩展一下,其实我们在做类型判断的时候习惯用typeof,typeof判断简单数据类型的时候其实是ok的。但是typeof有判断复杂数据类型不是很清晰,得到的基本是String或者Function
比如一下图示判断

但是,通过上述我们知道构造器的实例都有一个constructor的属性指向构造器。那其实我们直接用constructor便可以清晰地知道这个实例从哪里来。

3.原型对象
    每个函数对象都有一个prototype属性,这个属性指向函数的原型对象即prototype。
    所有的prototype会有一个默认的constuctor属性,指向函数对象本身。    

function Person(name,age,job){
this.name = name;
    this.age = age;
    this.job = job;
}
Person.prototype.sayName = function () {
    console.log(this.name);
};

let miya = new Person("miya",18,"engineer");
let tiffany = new Person("tiffany",18,"engineer");
miya.sayName();  //miya
tiffany.sayName();  //tiffany
console.log(miya.sayName == tiffany.sayName);  //true
console.log(Person.prototype.constructor == Person);  //true

通过:Person.prototype.constuctor = Person ,因为构造函数的实例是有一个constructor的属性指向构造函数的,我们可以得到结论其实Person.prototype也是Person的实例
    即:原型对象是构造函数的一个实例【原型对象(Function.prototype除外)是一个普通对象,而不是函数对象】

4.__proto__属性
    4.1 JS在创建对象的时候都会有一个__proto__指向它的构造函数的原型对象

其实,每个对象都有一个__proto__属性,但只有函数对象有prototype属性。
因此,可以得到以下这样图。

    4.2构造函数扩展
  而我们的构造函数本质上都是从Function new出来的。他们本质上都是Function的一个实例。都有一个__proto属性指向Function的原型,也有一个constructor属性指向Function。

    提示:Math,JSON是以对象形式存在的,无需new。他们的__proto__是Object.prototype 

因此可以得到以下的图示,所有的函数对象的__proto__都指向Function.prototype(是一个空函数)


5.函数对象
    1.所有的构造器都是通过Function new出来的,他们都是Function的实例,他们的__pro__都指向Function.prototype,甚至包括根构造器Object及Function本身。

Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

String.__proto__ === Function.prototype  // true
String.constructor == Function //true

Object.__proto__ === Function.prototype  // true
Object.constructor == Function // true

Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

    2.除Object.prototype外,所有的构造器的prototype的__proto__属性都指向Object.prototype

Function.prototype.__proto__ === Object.prototype; // true
Number.prototype.__proto__ === Object.prototype; // true
String.prototype.__proto__ === Object.prototype; // true
Array.prototype.__proto__ === Object.prototype; // true
Boolean.prototype.__proto__ === Object.prototype; // true
Object.prototype.__proto__ === Object.prototype; // true


    3.那Object.prototype的__proto__属性是指向null的。

Object.prototype.__proto__ === null; // true

    Function.prototype也是唯一一个typeof XXX.prototype为 function的prototype    
    推导Function.prototype.__proto__是什么呢? Object.prototype
    所有的构造器都继承Function.prototype的属性及方法 =>所有的构造器函数都是普通的js函数可以用Object的方法
    Object.prototype.__proto__ == null
 
 

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object

 
补充:
    null是一个独立数据类型,而不是一个空引用,只是期望此处引用一个对象 https://developer.mozilla.org...
    typeof null == Object是一个遗留bug

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104734.html

相关文章

  • 《你不知道的javascript》笔记_对象&原型

    摘要:上一篇你不知道的笔记写在前面这是年第一篇博客,回顾去年年初列的学习清单,发现仅有部分完成了。当然,这并不影响年是向上的一年在新的城市稳定连续坚持健身三个月早睡早起游戏时间大大缩减,学会生活。 上一篇:《你不知道的javascript》笔记_this 写在前面 这是2019年第一篇博客,回顾去年年初列的学习清单,发现仅有部分完成了。当然,这并不影响2018年是向上的一年:在新的城市稳定、...

    seasonley 评论0 收藏0
  • 【5】JavaScript 函数高级——原型原型深入理解(图解

    摘要:探索是如何判断的表达式如果函数的显式原型对象在对象的隐式原型链上,返回,否则返回是通过自己产生的实例案例案例重要注意的显示原型和隐式原型是一样的。面试题测试题测试题报错对照下图理解 原型与原型链深入理解(图解) 原型(prototype) 函数的 prototype 属性(图) 每个函数都有一个prototype属性,它默认指向一个Object空对象(即称为:原型对象) 原型对象中有...

    马龙驹 评论0 收藏0
  • javascript高级程序设计》笔记:原型图解

    摘要:不理解没关系,下面会结合图例分析上一篇高级程序设计笔记创建对象下一篇高级程序设计笔记继承参考之原型链的解读三张图搞懂的原型对象与原型链继承与原型链 文章直接从原型图解开始的,如果对一些概念不太清除,可以结合后面几节查看 1. 图解原型链 1.1 铁三角关系(重点) function Person() {}; var p = new Person(); showImg(https://s...

    vspiders 评论0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...

    enali 评论0 收藏0
  • javascript高级程序设计》笔记:继承

    摘要:继承和前面两篇文章中的知识非常相关,如果对函数创建原理和原型链不熟悉,请猛戳高级程序设计笔记创建对象高级程序设计笔记原型图解继承,通俗的说,就是将自身不存在的属性或方法,通过某种方式为自己所用文章分别介绍原型链继承继承借用构造函数继承组合继 继承和前面两篇文章中的知识非常相关,如果对函数创建原理和原型链不熟悉,请猛戳:《javascript高级程序设计》笔记:创建对象《javascri...

    JerryC 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<