浅谈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 相关文章推荐
地震发生中逃生十大法则
May 12 Javascript
关于viewport,Ext.panel和Ext.form.panel的关系
May 07 Javascript
js常用自定义公共函数汇总
Jan 15 Javascript
javascript跨域总结之window.name实现的跨域数据传输
Nov 01 Javascript
自动适应iframe右边的高度
Dec 22 Javascript
微信小程序中子页面向父页面传值实例详解
Mar 20 Javascript
vue下跨域设置的相关介绍
Aug 26 Javascript
如何利用node转发请求详解
Sep 17 Javascript
springboot+vue实现文件上传下载
Nov 17 Vue.js
jQuery实现增删改查
Dec 22 jQuery
关于Javascript闭包与应用的详解
Apr 22 Javascript
javascript的setTimeout()使用方法总结
Nov 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
php在线解压ZIP文件的方法
2014/12/30 PHP
100行PHP代码实现socks5代理服务器
2016/04/28 PHP
jquery 查找新建元素代码
2010/07/06 Javascript
写给想学习Javascript的朋友一点学习经验小结
2010/11/23 Javascript
javascript常见用法总结
2014/05/22 Javascript
jquery+ajax实现跨域请求的方法
2015/01/20 Javascript
JS实现图片局部放大或缩小的方法
2016/08/20 Javascript
easyui combobox开启搜索自动完成功能的实例代码
2016/11/08 Javascript
浅谈vue实现数据监听的函数 Object.defineProperty
2017/06/08 Javascript
微信页面弹出键盘后iframe内容变空白的解决方案
2017/09/20 Javascript
vue实现文章内容过长点击阅读全文功能的实例
2017/12/28 Javascript
nodejs实现范围请求的实现代码
2018/10/12 NodeJs
微信小程序解析富文本过程详解
2019/07/13 Javascript
Layui 数据表格批量删除和多条件搜索的实例
2019/09/04 Javascript
js实现简单的随机点名器
2020/09/17 Javascript
[52:52]DOTA2上海特级锦标赛C组资格赛#1 OG VS LGD第三局
2016/02/27 DOTA
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
Python 功能和特点(新手必学)
2015/12/30 Python
使用Python进行QQ批量登录的实例代码
2018/06/11 Python
TensorFlow实现iris数据集线性回归
2018/09/07 Python
对numpy中二进制格式的数据存储与读取方法详解
2018/11/01 Python
python实现连续图文识别
2018/12/18 Python
python 去除二维数组/二维列表中的重复行方法
2019/01/23 Python
Pytorch转keras的有效方法,以FlowNet为例讲解
2020/05/26 Python
python tqdm实现进度条的示例代码
2020/11/10 Python
css3中背景尺寸background-size详解
2014/09/02 HTML / CSS
Canvas与图片压缩的示例代码
2017/11/28 HTML / CSS
爱尔兰旅游网站:ebookers.ie
2020/01/24 全球购物
留学推荐信怎么写
2014/01/25 职场文书
甜点店创业计划书
2014/01/27 职场文书
校园之星获奖感言
2014/01/29 职场文书
事业单位绩效考核实施方案
2014/03/27 职场文书
vue实现同时设置多个倒计时
2021/05/20 Vue.js
Java面试题冲刺第十五天--设计模式
2021/08/07 面试题
Windows下用Nginx配置https服务器及反向代理的问题
2021/09/25 Servers
基于Redis结合SpringBoot的秒杀案例详解
2021/10/05 Redis