浅谈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 相关文章推荐
ie和firefox中img对象区别的困惑
Dec 27 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
Oct 18 Javascript
js数组转json并在后台对其解析具体实现
Nov 20 Javascript
Node.js node-schedule定时任务隔多少分钟执行一次的方法
Feb 10 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
May 09 Javascript
JavaScript中用getDate()方法返回指定日期的教程
Jun 09 Javascript
Javascript简单改变表单元素背景的方法
Jul 15 Javascript
JavaScript基础之AJAX简单的小demo
Jan 29 Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 Javascript
深入浅析Vue.js中 computed和methods不同机制
Mar 22 Javascript
jQuery实现鼠标移入显示蒙版效果
Jan 11 jQuery
Electron+vue从零开始打造一个本地播放器的方法示例
Oct 27 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
一个简易需要注册的留言版程序
2006/10/09 PHP
PHP类的反射用法实例
2014/11/03 PHP
php字符串函数学习之substr()
2015/03/27 PHP
select、radio表单回显功能实现避免使用jquery载入赋值
2013/06/08 Javascript
javascript如何判断输入的url是否正确
2014/04/11 Javascript
IE及IE6浏览器中判断JS文件加载成功失败的方法
2015/02/18 Javascript
jQuery 1.9.1源码分析系列(十三)之位置大小操作
2015/12/02 Javascript
JavaScript判断DIV内容是否为空的方法
2016/01/29 Javascript
js 将图片连接转换成base64格式的简单实例
2016/08/10 Javascript
完美解决input[type=number]无法显示非数字字符的问题
2017/02/28 Javascript
Angular directive递归实现目录树结构代码实例
2017/05/05 Javascript
基于JavaScript实现表格滚动分页
2017/11/22 Javascript
微信小程序radio组件使用详解
2018/01/31 Javascript
JavaScript和TypeScript中的void的具体使用
2019/09/12 Javascript
jquery添加div实现消息聊天框
2020/02/08 jQuery
小程序实现上下切换位置
2020/11/16 Javascript
django自带的server 让外网主机访问方法
2018/05/14 Python
python如何实现不可变字典inmutabledict
2020/01/08 Python
linux系统下pip升级报错的解决方法
2021/01/31 Python
采用专利算法搜索最廉价的机票:CheapAir
2016/09/10 全球购物
巴西在线鞋店:Shoestock
2017/10/28 全球购物
wedgwood加拿大官网:1759年成立的英国国宝级陶瓷餐具品牌
2018/07/17 全球购物
西安当代医院管理研究院笔试题
2015/12/11 面试题
技能比赛获奖感言
2014/02/14 职场文书
讲文明树新风公益广告宣传方案
2014/02/25 职场文书
老干部工作先进集体事迹材料
2014/05/21 职场文书
个人授权委托书范本
2014/09/14 职场文书
业务员工作态度散漫检讨书
2014/11/02 职场文书
钳工实训报告总结
2014/11/04 职场文书
表扬稿范文
2015/01/17 职场文书
给老婆道歉的话
2015/01/20 职场文书
会议邀请函
2015/01/30 职场文书
提档介绍信范文
2015/10/22 职场文书
考生诚信考试承诺书(2016版)
2016/03/25 职场文书
vue使用element-ui按需引入
2022/05/20 Vue.js
使用pd.merge表连接出现多余行的问题解决
2022/06/16 Python