彻底深刻理解js原型链之prototype,proto以及constructor(一)
前言
以下概念请花费一定的时间彻底理解,才能进行下一步,思考题一定要思考,这样才能彻底掌握原型链的知识点,教程中如果有任何的错误不足请指正!
函数对象
由function创造出来的函数,比如:
function a(){};
var b=function(){};
系统内置的函数对象
Function,Object,Array,String,Number
只有函数对象才有 prototype属性 ,重要的事情说三遍!
思考: js的引用数据类型都属于函数对象吗?
普通对象
除开函数对象之外的对象都是普通对象
var b='qwe'; // b 是字符串类型,属于普通对象
var c=123;; // c 是数字类型,属于普通对象
思考:js有五种基本类型:Undefined,Null,Boolean,Number和String,他们都是属于普通对象吗?
原型对象
prototype属性也叫原型对象,主要是为了实现继承和共享属性;
可以说我们的每一次编程,内在都有原型对象来发挥着作用,如果你没有掌握原型对象的含义,那么你的js还没有真正的入门!
function a(){};
首先对象 a 是由Function创造出来,是函数对象;那么根据我们以上的教程,a 就有了prototype属性,那么这个原型对象是怎么创造出来的呢? 来看下面这个例子:
var temp = new a();
a.prototype=new Object();
a.prototype = temp;
那么a的prototype属性就是这样创造出来的;
思考:原型对象prototype 属于函数对象吗?
指针proto
JavaScript中,万物皆对象!所有的对象obj都具有proto属性(null和undefined除外),可称为隐式原型,一个对象的隐式原型指向构造该对象的构造函数的原型
请看以下例子帮助理解:
function a(){};
var obj=new a();
console.log(a.__proto__===Function.prototype); //true
console.log(a.prototype.__proto__===Object.prototype); //true
console.log(obj.__proto__===a.prototype); //true
思考一下,var obj={}; obj.prototype.proto指向谁?
构造函数属性constructor
假设 obj 是由函数对象 a 由new运算创造出来的,那么obj的constructor 的属性就存放着一个对 a 的引用,通过这个构造函数,我们还可以为 a添加其他属性和方法, 这个属性的最初设计是为了检测对象的数据类型,不过后来人们通过此属性的特性做了更多的事情
请看以下例子:
function a(){};
var obj=new a();
obj.constructor.b=`我是a的新的属性`;
console.log(a.b); //我是a的新的属性
console.log(a.constructor===Function); //true
console.log(a.prototype.constructor===a); //true
console.log(obj.constructor===a); //true
函数a是由Function创造出来,那么它的constructor指向的Function,obj是由new a()方式创造出来,那么obj.constructor理应指向a
思考:a.prototype.proto.constructor指向谁?
思考题解答
函数对象思考题解答
思考: js的引用数据类型都属于函数对象吗?
引用类型值:指的是那些保存在堆内存中的对象,意思是,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象
那么数组,普通对象,函数对象都算是引用数据类型,引用数据类型范围包含函数对象的范围
普通对象思考题解答
思考:js有五种基本类型:Undefined,Null,Boolean,Number和String,他们都是属于普通对象吗?
基本类型值:指的是保存在栈内存中的简单数据段;除开函数对象之外的对象都是普通对象,那么普通对象范围是包含基本数据类型的
事实上(函数对象,普通对象)以及(基本数据类型,引用数据类型)是在不同角度对js变量进行的定义
原型对象思考题解答
思考:原型对象prototype 属于函数对象吗?
事实上 这个问题要进行分别回答:
Function.prototype 属于函数对象,其他对象的prototype属于普通对象
function a(){};
console.log(typeof Function.prototype); // function
console.log(typeof a.prototype); //object
前面说过prototype的创造过程
var temp = new a();
a.prototype = temp;
这里temp当然就是普通对象啦,但是看下Function的prototype创造过程
var a = new Function();
Function.prototype = a;
看明白了把,Function的prototype为什么是函数对象了吧?回忆一下函数对象的定义吧!
指针proto思考题解答
思考一下,var obj={}; obj.prototype.proto指向谁?
这里分步思考: 1, obj只是一个普通对象 2, 什么类型的对象是有prototype属性的?当然是函数对象 3, 所以obj是没有prototype属性的 4, 所以obj.prototype===undefined 5, 所以此题的最终问题是:undefined.proto指向什么 6, 所有的对象obj都具有proto属性(null和undefined除外)!所以答案是 js报错(有没有一种被我坑了的感觉)
构造器constructor思考题解答
思考:a.prototype.proto.constructor指向谁?
function a(){};
这里继续分解题目: 1, a.prototype指向a的一个实例,我们已经多次强调了,而且属于普通对象 2, proto定义为:指向创造obj对象的函数对象的prototype属性,所以看下谁创造了a.prototype,因为a.prototype是普通对象,类型为object,那么是Object创造了它, 3, 那么显而易见a.prototype.proto指向了Object.prototype 4, 那么题目简化为Object.prototype.constructor指向谁 5, 继续分解题目,Object.prototype为基本对象,那么就是Object创造了它,那么它的constructor就指向了Object
Object.prototype.constructor===Object //true
不知道你晕不晕,我有点晕,这产生了蛋生鸡还是鸡生蛋的问题啦~
放心,还是有尽头的 :
Object.prototype.__proto__===null //true
这个例子告诉我们是 是null创造了一切,这不就是易经中的:“道生一,一生二,二生三,三生万物!”
作者:宜信技术学院 刘晓敏
- 比特币分叉倒计时,糖果福利又来了
- 执行git push出现"Everything up-to-date"
- linux下EOF写法梳理
- 用AngularJS来实现异步数据的购物车功能设计
- span不如div的地方
- 分布式监控系统Zabbix--完整安装记录(7)-使用percona监控MySQL
- 10x Python开发者必读:本月Python文章TOP 10
- Linux下更换默认yum源为网易yum源的操作记录
- yum源使用的几个报错小总结
- JQuery笔记(一)
- Haproxy和Nginx负载均衡测试效果对比记录
- JQuery笔记(三) jquery的用途
- Heartbeat使用梳理
- JQuery笔记(二) animate支持的属性
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 前端也能学算法:由浅入深讲解动态规划
- 轻松理解JS中的面向对象,顺便搞懂prototype和__proto__
- 前端也能学算法:由浅入深讲解贪心算法
- web.py指南性说明
- this到底指向啥?看完这篇就知道了!
- 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS小数计算不准问题
- python 实现 php 的 var_dump 功能
- RSA初探,聊聊怎么破解HTTPS
- 深入解析Underscore.js源码架构
- python正向连接后门
- setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop
- emlog全版本CSRF加用户xsser.me模块
- 从发布订阅模式入手读懂Node.js的EventEmitter源码
- 手写一个Promise/A+,完美通过官方872个测试用例
- 浅析白盒审计中的字符编码及SQL注入