浅谈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 相关文章推荐
转一个日期输入控件,支持FF
Apr 27 Javascript
Add Formatted Data to a Spreadsheet
Jun 12 Javascript
FireFox与IE 下js兼容触发click事件的代码
Nov 20 Javascript
input 和 textarea 输入框最大文字限制的jquery插件
Oct 27 Javascript
JS判断页面加载状态以及添加遮罩和缓冲动画的代码
Oct 11 Javascript
JS 实现Json查询的方法实例
Apr 12 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
Oct 08 Javascript
JavaScript提高网站性能优化的建议(二)
Jul 24 Javascript
JavaScript省市级联下拉菜单实例
Feb 14 Javascript
js实现动态显示时间效果
Mar 06 Javascript
Vue中正确使用jQuery的方法
Oct 30 jQuery
关于layui 下拉列表的change事件详解
Sep 20 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
Syphon 虹吸式咖啡壶冲煮–拨动法
2021/03/03 冲泡冲煮
国外比较好的几个的Php开源建站平台小结
2010/04/22 PHP
探讨:如何编写PHP扩展
2013/06/13 PHP
PHP中session变量的销毁
2014/02/27 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
2016/11/14 PHP
php如何计算两坐标点之间的距离
2018/12/29 PHP
javascript vvorld 在线加密破解方法
2008/11/13 Javascript
Mootools 1.2教程 设置和获取样式表属性
2009/09/15 Javascript
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
使用jquery实现鼠标滑过弹出更多相关信息层附源码下载
2015/11/23 Javascript
javascript省市区三级联动下拉框菜单实例演示
2015/11/29 Javascript
JS实现CheckBox复选框全选、不选或全不选功能
2020/07/28 Javascript
移动端日期插件Mobiscroll.js使用详解
2016/12/19 Javascript
BootStrap栅格系统、表单样式与按钮样式源码解析
2017/01/20 Javascript
JavaScript定义函数_动力节点Java学院整理
2017/06/27 Javascript
BootStrap数据表格实例代码
2017/09/13 Javascript
vue中实现移动端的scroll滚动方法
2018/03/03 Javascript
Vue.js+Layer表格数据绑定与实现更新的实例
2018/03/07 Javascript
如何使用pm2快速将项目部署到远程服务器
2019/03/12 Javascript
[45:44]完美世界DOTA2联赛PWL S2 FTD vs PXG 第一场 11.27
2020/12/01 DOTA
tensorflow实现图像的裁剪和填充方法
2018/07/27 Python
简单谈谈python基本数据类型
2018/09/26 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
Python 仅获取响应头, 不获取实体的实例
2019/08/21 Python
python之array赋值技巧分享
2019/11/28 Python
如何使用selenium和requests组合实现登录页面
2020/02/03 Python
自定义实现 PyQt5 下拉复选框 ComboCheckBox的完整代码
2020/03/30 Python
python3.x中安装web.py步骤方法
2020/06/23 Python
英国大码女性时装零售商:Evans
2018/08/29 全球购物
全球速卖通俄罗斯站:AliExpress俄罗斯
2019/06/17 全球购物
Java平台和其他软件平台有什么不同
2015/06/05 面试题
数学系毕业生的自我评价
2014/01/10 职场文书
领导党性分析材料
2014/02/15 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
2016入党培训心得体会范文
2016/01/08 职场文书
详解NumPy中的线性关系与数据修剪压缩
2022/05/25 Python