浅谈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 AJAX回调函数this指向问题
Feb 08 Javascript
jquery ajax例子返回值详解
Sep 11 Javascript
修改file按钮的默认样式实现代码
Apr 23 Javascript
JavaScript实现数组随机排序的方法
Jun 26 Javascript
jQuery实用技巧必备(中)
Nov 03 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
Dec 13 Javascript
Jquery Easyui菜单组件Menu使用详解(15)
Dec 18 Javascript
解决JS外部文件中文注释出现乱码问题
Jul 09 Javascript
angular-tree-component的使用详解
Jul 30 Javascript
vue项目部署到Apache服务器中遇到的问题解决
Aug 24 Javascript
详解如何在vscode里面调试js和node.js的方法步骤
Dec 24 Javascript
JS实现秒杀倒计时特效
Jan 02 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的FTP学习(一)
2006/10/09 PHP
php smarty模版引擎中的缓存应用
2009/12/11 PHP
php入门学习知识点七 PHP函数的基本应用
2011/07/14 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
laravel框架路由分组,中间件,命名空间,子域名,路由前缀实例分析
2020/02/18 PHP
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
JS获取并操作iframe中元素的方法
2013/03/21 Javascript
JS实现仿google、百度搜索框输入信息智能提示的实现方法
2015/04/20 Javascript
如何使用HTML5地理位置定位功能
2015/04/27 Javascript
关于Bootstrap弹出框无法调用问题的解决办法
2016/03/10 Javascript
jquery删除数组中重复元素
2016/12/05 Javascript
jquery实现自适应banner焦点图
2017/02/16 Javascript
浅谈React Native 中组件的生命周期
2017/09/08 Javascript
vue浏览器返回监听的具体步骤
2021/02/03 Vue.js
[58:37]Serenity vs Fnatic 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[01:16]DOTA2小知识课堂 Ep.03 芒果树无伤肉山
2019/12/05 DOTA
python常规方法实现数组的全排列
2015/03/17 Python
python实现unicode转中文及转换默认编码的方法
2017/04/29 Python
python高阶爬虫实战分析
2018/07/29 Python
使用PIL(Python-Imaging)反转图像的颜色方法
2019/01/24 Python
python实现五子棋小游戏
2020/03/25 Python
python 读取修改pcap包的例子
2019/07/23 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
python tqdm 实现滚动条不上下滚动代码(保持一行内滚动)
2020/02/19 Python
pyautogui自动化控制鼠标和键盘操作的步骤
2020/04/01 Python
django Model层常用验证器及自定义验证器详解
2020/07/15 Python
全球最大的跑步用品商店:Road Runner Sports
2016/09/11 全球购物
毕业生的自我鉴定
2013/10/29 职场文书
社区工作者先进事迹
2014/01/18 职场文书
新闻学专业职业生涯规划范文:我的人生我做主
2014/09/12 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
部队2014年终工作总结
2014/11/27 职场文书
前台接待岗位职责范本
2015/04/03 职场文书
Python词云的正确实现方法实例
2021/05/08 Python
IDEA2021.2配置docker如何将springboot项目打成镜像一键发布部署
2021/09/25 Java/Android
i5-10400f处理相当于i7多少水平
2022/04/19 数码科技