浅谈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 相关文章推荐
jQuery实现鼠标移到元素上动态提示消息框效果
Oct 20 Javascript
详解JavaScript中的forEach()方法的使用
Jun 08 Javascript
简单讲解jQuery中的子元素过滤选择器
Apr 18 Javascript
js实现按钮控制带有停顿效果的图片滚动
Aug 30 Javascript
javascript 组合按键事件监听实现代码
Feb 21 Javascript
使用vue打包进行云服务器上传的问题
Mar 02 Javascript
解决vue+webpack项目接口跨域出现的问题
Aug 10 Javascript
vue实现打地鼠小游戏
Aug 21 Javascript
vue移动端写的拖拽功能示例代码
Sep 09 Javascript
解决vue项目运行提示Warnings while compiling.警告的问题
Sep 18 Javascript
VUE+Element实现增删改查的示例源码
Nov 23 Vue.js
一篇文章让你搞懂JavaScript 原型和原型链
Nov 23 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
在PHP的图形函数中显示汉字
2006/10/09 PHP
提升PHP速度全攻略
2006/10/09 PHP
php获取url参数方法总结
2014/11/13 PHP
PHP实现权限管理功能示例
2017/09/22 PHP
脚本吧 - 幻宇工作室用到js,超强推荐base.js
2006/12/23 Javascript
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
2013/04/17 Javascript
Javascript removeChild()删除节点及删除子节点的方法
2015/12/27 Javascript
详细谈谈javascript的对象
2016/07/31 Javascript
Javascript基础回顾之(一) 类型
2017/01/31 Javascript
关于js中的鼠标事件总结
2017/07/11 Javascript
jQuery实现的监听导航滚动置顶状态功能示例
2018/07/23 jQuery
JS中的防抖与节流及作用详解
2019/04/01 Javascript
使用element-ui的el-menu导航选中后刷新页面保持当前选中状态
2019/07/19 Javascript
[45:56]Ti4正赛第一天 VG vs NEWBEE 3
2014/07/19 DOTA
六个窍门助你提高Python运行效率
2015/06/09 Python
详解Python编程中time模块的使用
2015/11/20 Python
Python与人工神经网络:使用神经网络识别手写图像介绍
2017/12/19 Python
Python IDE Pycharm中的快捷键列表用法
2019/08/08 Python
python3 requests库文件上传与下载实现详解
2019/08/22 Python
TensorFlow加载模型时出错的解决方式
2020/02/06 Python
利用Python自动化操作AutoCAD的实现
2020/04/01 Python
Python map及filter函数使用方法解析
2020/08/06 Python
Python爬虫自动化获取华图和粉笔网站的错题(推荐)
2021/01/08 Python
京东全球售:直邮香港,澳门,台湾,美国,澳大利亚等地区
2017/09/24 全球购物
美国购买肉、鸭、家禽、鹅肝和熟食网站:D’Artagnan
2018/11/13 全球购物
ECCO俄罗斯官网:北欧丹麦鞋履及皮具品牌
2020/06/26 全球购物
Lookfantastic阿联酋官网:英国知名美妆护肤购物网站
2020/05/26 全球购物
学校感恩教育活动总结
2014/07/07 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
大学生团日活动总结
2015/05/06 职场文书
赵氏孤儿观后感
2015/06/09 职场文书
获奖感言范文
2015/07/31 职场文书
导游词之无锡华莱坞
2019/12/02 职场文书
python的html标准库
2022/04/29 Python
MySQL示例讲解数据库约束以及表的设计
2022/06/16 MySQL