浅谈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 相关文章推荐
让焦点自动跳转
Jul 01 Javascript
jquery使用ajax实现微信自动回复插件
Apr 28 Javascript
javasript实现密码的隐藏与显示
May 08 Javascript
js+cookies实现悬浮购物车的方法
May 25 Javascript
Bootstrap Table表格一直加载(load)不了数据的快速解决方法
Sep 17 Javascript
jQuery实现的背景颜色渐变动画效果示例
Mar 24 jQuery
JS实现的JSON数组去重算法示例
Apr 11 Javascript
Vue实现购物车详情页面的方法
Aug 20 Javascript
layui自定义工具栏的方法
Sep 19 Javascript
vue仿ios列表左划删除
Sep 26 Javascript
原生js实现五子棋游戏
May 28 Javascript
Vue+TypeScript中处理computed方式
Apr 02 Vue.js
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出现Cannot modify header information问题的解决方法大全
2008/04/09 PHP
simplehtmldom Doc api帮助文档
2012/03/26 PHP
PHP过滤黑名单关键字的方法
2014/12/01 PHP
php创建session的方法实例详解
2015/01/27 PHP
php生成PDF格式文件并且加密
2015/06/22 PHP
php resizeimage 部分jpg文件 生成缩略图失败的原因分析及解决办法
2016/03/23 PHP
PHP实现的激活用户注册验证邮箱功能示例
2017/06/06 PHP
ThinkPHP5 验证器的具体使用
2018/05/31 PHP
JavaScript 参考教程
2006/12/29 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
2011/03/03 Javascript
Javascript监视变量变化的方法
2015/06/09 Javascript
Jquery中map函数的用法
2016/06/03 Javascript
原生js二级联动效果
2017/06/20 Javascript
vue弹窗组件使用方法
2018/04/28 Javascript
解决Vue开发中对话框被遮罩层挡住的问题
2018/11/26 Javascript
详解基于React.js和Node.js的SSR实现方案
2019/03/21 Javascript
js实现简单掷骰子小游戏
2019/10/24 Javascript
[01:23:59]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 VP vs Secret
2018/04/03 DOTA
python传递参数方式小结
2015/04/17 Python
matplotlib.pyplot画图 图片的二进制流的获取方法
2018/05/24 Python
django rest framework 数据的查找、过滤、排序的示例
2018/06/25 Python
python爬取微信公众号文章
2018/08/31 Python
Django 对IP访问频率进行限制的例子
2019/08/30 Python
python实现输入的数据在地图上生成热力图效果
2019/12/06 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Python urlencode和unquote函数使用实例解析
2020/03/31 Python
HTML5 Canvas的事件处理介绍
2015/04/24 HTML / CSS
美国购买和销售礼品卡平台:Raise
2017/01/13 全球购物
GetYourGuide台湾:预订旅游活动、景点和旅游项目
2019/06/10 全球购物
小露珠教学反思
2014/04/30 职场文书
交通安全责任书范本
2014/07/24 职场文书
学生会竞选演讲稿学习部
2014/08/25 职场文书
2014党员整改措施思想汇报
2014/10/07 职场文书
敬老院志愿者活动总结
2015/05/06 职场文书
Win11远程连接不上怎么办?Win11远程桌面用不了的解决方法
2022/08/05 数码科技