浅谈JS的原型和继承


Posted in Javascript onMay 08, 2019

参考文献

JavaScript原型与继承的秘密

__proto__

除null和undefined,JS中的所有数据类型都有这个属性; 它表示当我们访问一个对象的某个属性时,如果该对象自身不存在该属性, 就从它的__proto__属性上继续查找,以此类推,直到找到,若找到最后还是没有找到,则结果为undefined

我们把一个对象的__proto__属性所指向的对象叫该对象的原型;我们可以修改一个对象的原型来让这个对象拥有某种属性或某个方法

// 修改一个Number类型的值的原型
const num = 1;
num.__proto__.name = "My name is 1";
console.log(num.name); // My name is 1
 
// 修改一个对象的原型
const obj = {};
obj.__proto__.name = "dreamapple";
console.log(obj.name); // dreamapple

需注意的是,__proto__属性虽多数浏览器支持,但其实它仅在ECMAScript 2015规范中才被准确定义, 目的是为了给这个传统的功能定制一个标准,以确保浏览器间的兼容性。通过使用__proto__属性来修改一个对象的原型非常慢且影响性能。 所以,若想获取一个对象的原型,推荐用Object.getPrototypeOf 或Reflect.getPrototypeOf,设置一个对象的原型推荐用Object.setPrototypeOf或Reflect.setPrototypeOf

prototype

首先要记住的是,该属性一般只存在于函数对象上; 只要是能作为构造器的函数,都包含这个属性。即只要这个函数能通过new生成一个新对象, 那么这个函数肯定具有prototype属性。因为我们自定义的函数都可通过new生成一个对象,所以我们自定义的函数都有prototype 这个属性

// 函数字面量
console.log((function(){}).prototype); // {constructor: ƒ}
 
// Date构造器
console.log(Date.prototype); // {constructor: ƒ, toString: ƒ, toDateString: ƒ, toTimeString: ƒ, toISOString: ƒ, …}
 
// Math.abs 不是构造器,不能通过new操作符生成一个新的对象,所以不含有prototype属性
console.log(Math.abs.prototype); // undefined

prototype属性有什么作用呢?作用就是:函数通过new生成的一个对象, 这个对象的原型(__proto__)指向该函数的prototype属性:

// 其中F表示一个自定义的函数或者是含有prototype属性的内置函数
new F().__proto__ === F.prototype // true
 
// 通过函数字面量定义的函数的__proto__属性都指向Function.prototype
(function(){}).__proto__ === Function.prototype // true
 
// 通过对象字面量定义的对象的__proto__属性都是指向Object.prototype
({}).__proto__ === Object.prototype // true
 
// Object函数的原型的__proto__属性指向null
Object.prototype.__proto__ === null // true
 
// 因为Function本身也是一个函数,所以Function函数的__proto__属性指向它自身的prototype
Function.__proto__ === Function.prototype // true
 
// 因为Function的prototype是一个对象,所以Function.prototype的__proto__属性指向Object.prototype
Function.prototype.__proto__ === Object.prototype // true

constructor

constructor表示一个对象的构造函数,除null和undefined,JS中的所有数据类型都有这个属性; 我们可通过下面的代码来验证一下:

null.constructor // Uncaught TypeError: Cannot read property 'constructor' of null ...
undefined.constructor // Uncaught TypeError: Cannot read property 'constructor' of undefined ...
 
(true).constructor // ƒ Boolean() { [native code] }
(1).constructor // ƒ Number() { [native code] }
"hello".constructor // ƒ String() { [native code] }

一个对象的constructor属性确切地说并不是存在这个对象上面的; 而是存在这个对象的原型上(如果是多级继承需手动修改原型的constructor属性),我们可用下面的代码来解释一下:

const F = function() {};
// 当我们定义一个函数的时候,这个函数的prototype属性上面的constructor属性指向自己本身
F.prototype.constructor === F; // true

对JS的原始类型(string, number, boolean, null, undefined, symbol (new in ECMAScript 2015)),它们的constructor属性是只读的,不可修改:

(1).constructor = "something";
console.log((1).constructor); // 输出 ƒ Number() { [native code] }

如果真想改这些原始类型的constructor属性,也不是不可以:

Number.prototype.constructor = "number constructor";
(1).constructor = 1;
console.log((1).constructor); // 输出 number constructor

当然上面的方式不推荐

以上所述是小编给大家介绍的JS原型和继承详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
javascript加号"+"的二义性说明
Mar 04 Javascript
jQuery源码解读之addClass()方法分析
Feb 20 Javascript
[原创]Javascript 实现广告后加载 可加载百度谷歌联盟广告
May 11 Javascript
浅谈js内置对象Math的属性和方法(推荐)
Sep 19 Javascript
Bootstrap CSS组件之导航(nav)
Dec 17 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
May 25 Javascript
浅析vue深复制
Jan 29 Javascript
解决webpack+Vue引入iView找不到字体文件的问题
Sep 28 Javascript
基于Angular中ng-controller父子级嵌套的相关属性详解
Oct 08 Javascript
JS编写兼容IE6,7,8浏览器无缝自动轮播
Oct 12 Javascript
ES6中的迭代器、Generator函数及Generator函数的异步操作方法
May 12 Javascript
Node 模块原理与用法详解
May 13 Javascript
vue使用vuex实现首页导航切换不同路由的方法
May 08 #Javascript
微信小程序封装自定义弹窗的实现代码
May 08 #Javascript
Vue.js轮播图走马灯代码实例(全)
May 08 #Javascript
深入浅析vue-cli@3.0 使用及配置说明
May 08 #Javascript
js实现继承的方法及优缺点总结
May 08 #Javascript
微信小程序人脸识别功能代码实例
May 07 #Javascript
iphone刘海屏页面适配方法
May 07 #Javascript
You might like
15种PHP Encoder的比较
2007/04/17 PHP
用mysql触发器自动更新memcache的实现代码
2009/10/11 PHP
PHP执行zip与rar解压缩方法实现代码
2010/12/05 PHP
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
2012/01/21 Javascript
jQuery学习笔记之总体架构
2014/06/03 Javascript
技术男用来对妹子表白的百度首页
2014/07/23 Javascript
jQuery控制文本框只能输入数字和字母及使用方法
2016/05/26 Javascript
jQuery实现可以编辑的表格实例详解【附demo源码下载】
2016/07/09 Javascript
深入理解Node.js 事件循环和回调函数
2016/11/02 Javascript
jQuery插件echarts实现的循环生成图效果示例【附demo源码下载】
2017/03/04 Javascript
jQuery Autocomplete简介_动力节点Java学院整理
2017/07/17 jQuery
vue.js图片转Base64上传图片并预览的实现方法
2018/08/02 Javascript
JS实现json数组排序操作实例分析
2019/10/28 Javascript
Python的类实例属性访问规则探讨
2015/01/30 Python
Python编程之变量赋值操作实例分析
2017/07/24 Python
import的本质解析
2017/10/30 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
python3 tkinter实现添加图片和文本
2019/11/26 Python
简单了解python元组tuple相关原理
2019/12/02 Python
基于pytorch的lstm参数使用详解
2020/01/14 Python
Python标准库itertools的使用方法
2020/01/17 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
Python基于Twilio及腾讯云实现国际国内短信接口
2020/06/18 Python
中国综合性网上购物商城:当当(网上卖书起家)
2016/11/16 全球购物
美国专业级皮肤病和spa品质护肤品的高级零售网站:SkinCareRx
2017/02/06 全球购物
欧洲、亚洲、非洲和拉丁美洲的度假套餐:Great Value Vacations
2019/03/30 全球购物
机电专业大学生求职信
2013/10/04 职场文书
老公给老婆的道歉信
2014/01/10 职场文书
安全目标管理责任书
2014/07/25 职场文书
党的群众路线教育实践活动对照检查剖析材料
2014/10/09 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
初中语文教师研修日志
2015/11/13 职场文书
承诺书应该怎么写?
2019/09/10 职场文书
如何用python绘制雷达图
2021/04/24 Python
mysql优化之query_cache_limit参数说明
2021/07/01 MySQL
使用python创建股票的时间序列可视化分析
2022/03/03 Python