博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中的prototype、__proto__、constructor
阅读量:6505 次
发布时间:2019-06-24

本文共 2964 字,大约阅读时间需要 9 分钟。

哪些对象有原型?

所有的对象在默认情况下都有一个原型,因为原型本身也是对象,所以每个原型自身又有一个原型(只有一种例外,默认的对象原型在原型链的顶端)

prototype属性

prototype是每个函数对象都具有的属性,被称为原型对象,而__proto__属性才是每个对象才有的属性。一旦原型对象被赋予属性和方法,那么由相应的构造函数创建的实例会继承prototype上的属性和方法

为什么只有函数才有prototype属性?ES规范就这么定的。

当你创建函数时,JS会为这个函数自动添加prototype属性, 值是一个有 constructor 属性的对象,不是空对象。而一旦你把这个函数当作构造函数(constructor)调用(即通过new关键字调用),那么JS就会帮你创建该构造函数的实例,实例继承构造函数prototype的所有属性和方法(实例通过设置自己的__proto__指向承构造函数的prototype来实现这种继承)

constructor属性和prototype属性

每个函数都有prototype属性,而这个prototype的constructor属性会指向这个函数。

proto

对象__proto__属性的值就是它所对应的原型对象

var one = {x: 1};var two = new Object();one.__proto__ === Object.prototype // truetwo.__proto__ === Object.prototype // trueone.toString === one.__proto__.toString // true

下面我们来看个例子来帮助理解这三个属性

function Person(name){this.name = name;}var p1 = new Person('louis');console.log(Person.prototype);//Person原型 {constructor: Person(name),__proto__: Object}console.log(p1.prototype);//undefinedconsole.log(Person.__proto__);//空函数, function(){}console.log(p1.__proto__ == Person.prototype);//true

我们发现, Person.prototype(原型) 默认拥有两个属性:

constructor 属性, 指向构造器, 即Person本身
proto 属性, 指向一个空的Object 对象
而p1作为非函数对象, 自然就没有 prototype 属性

下面来看看__proto__属性:

p1.__proto__ 属性 指向的是 构造器(Person) 的原型, 即 Person.prototype.

这里我们发现: 原型链查询时, 正是通过这个属性(__proto__) 链接到构造器的原型, 从而实现查询的层层深入.
Person.__proto__ 属性 指向的是一个空函数( function(){} ),

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

Person 是构造器也是函数(function), Person的__proto__ 属性自然就指向 函数(function)的原型, 即 Function.prototype.

这说明 所有的构造器都继承于Function.prototype

既然所有的构造器都来自于Function.prototype, 那么Function.prototype 到底是什么呢?

我们借用 typeof 运算符来看看它的类型.

console.log(typeof Function.prototype) // "function"

实际上, Function.prototype也是唯一一个typeof XXX.prototype为 “function”的prototype。其它的构造器的prototype都是一个对象。如下:

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

既然Function.prototype 的类型是函数, 那么它会拥有 proto 属性吗, Function.prototype.__proto__ 会指向哪里呢? 会指向对象的原型吗? 请看下方:

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

透过上方代码, 且我们了解到: Function.prototype 的类型是函数, 也就意味着一个函数拥有 proto 属性, 并且该属性指向了对象(Object)构造器的原型. 这意味着啥?

根据我们在前面了解到的: proto 是对象的内部属性, 它指向构造器的原型.

这意味着 Function.prototype 函数 拥有了一个对象的内部属性, 并且该属性还恰好指向对象构造器的原型. 它是一个对象吗? 是的, 它一定是对象. 它必须是.实际上, JavaScript的世界观里, 函数也是对象, 函数是一等公民.

这说明所有的构造器既是函数也是一个普通JS对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。

Object.prototype

函数的 proto 属性指向 Function.prototype, 如: Person.__proto__ —> Function.prototype

Function.prototype 函数的 proto 属性指向 Object.prototype, 如: Function.prototype.__proto__ —> Object.prototype.

那么Object.prototype.__proto__ 指向什么呢?

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

转载地址:http://abqyo.baihongyu.com/

你可能感兴趣的文章
06-验证码-基本功能实现
查看>>
Java数据结构与算法(六) 希尔排序
查看>>
canvas学习笔记
查看>>
IntelliJ Idea下Go项目开启Debug调试
查看>>
elasticsearch安装步骤
查看>>
PHP获取Cookie模拟登录CURL(转)
查看>>
PHP-权限控制类(转)
查看>>
CSS3秘笈第三版涵盖HTML5学习笔记9~12章
查看>>
bzoj1044木棍分割
查看>>
leetcode-136-Single Number
查看>>
微信小程序笔记<五> 页面管理及生命周期(route)——getCurrentPages()
查看>>
http服务器小项目
查看>>
JS案例:Jq中的fadeOut和fadeIn实现简单轮播(没完善,简单实现)
查看>>
一些数学上的名词及操作
查看>>
C# DataGridVie利用model特性动态加载列
查看>>
IPv6 地址分类
查看>>
<%@ include %>指令和<jsp:include>区别
查看>>
因为文件组 'PRIMARY' 已满 解决办法
查看>>
Flume 读取实时更新的日志文件
查看>>
HDU 2049
查看>>