JavaScript进阶之原型链
对象
function f1(){
};
typeof f1 //"function"函数对象 var o1 = new f1();
typeof o1 //"object"普通对象 var o2 = {};
typeof o2 //"object"普通对象
JavaScript中将对象分为普通对象和函数对象。
使用函数对象可以创建普通对象,普通对象没法创建函数对象。
凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。
原型对象(prototype)
Prototype
Prototype有原型、蓝本的意思,只有函数对象才会有原型(prototype)。
所谓原型,就是函数用来创建实例(普通)对象的蓝本(原型)。
每个原型都有一个 constructor 属性指向关联的构造函数。
__proto__
每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型(prototype)。
constructor
构造函数,即用来创建实例的函数,即关联的函数对象本身。
验证
在火狐或者谷歌浏览器控制台中新建一个普通对象,查看他的属性。
var o = {};
console.log(o.prototype); //undefined 普通对象没有prototype属性
console.log(o instanceof Object); //true o是Object的实例
console.log(o.__proto__ === Object.prototype) //true o的__proto__指向Object的prototype
console.log(Object === Object.prototype.constructor) //true Object.prototype.constructor指向Object本身
console.log(Object.prototype.constructor) //function Object() 函数对象原型的构造函数指向这个函数
console.log(Object.prototype.__proto__); //null Object.prototype的__proto__为null,为原型链终点
新建一个函数对象,查看他的属性。
function Demo() { };
var f1 = new Demo();
console.log(f1.prototype); //undefined 通过函数对象穿创建的是普通对象,Demo本身是函数对象
console.log(f1 instanceof Demo); //true f1是Demo的实例
console.log(f1.__proto__ === Demo.prototype); //true
console.log(Demo === Demo.prototype.constructor);//true
console.log(Demo.prototype.__proto__ === Object.prototype);//true Demo原型的__proto__指向Object的原型prototype
console.log(Object.prototype.__proto__); //null
原型的重要功能就是用作继承。
原型链(prototype chain)
javascript中,每个对象都会在内部生成一个__proto__ 属性,当我们访问一个对象属性时,如果这个对象不存在就回去__proto__ 指向的对象里面找,一层一层找下去,这就是javascript原型链的概念。
提升:
- 在原型链上查找属性比较耗时,对性能有副作用,这在性能要求苛刻的情况下很重要。另外,试图访问不存在的属性时会遍历整个原型链。
- 遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来。要检查对象是否具有自己定义的属性,而不是其原型链上的某个属性,则必须使用对象从Object.prototype继承的 hasOwnProperty 方法。(使用 for in 遍历对象时推荐总是使用 hasOwnProperty 方法)
继承
JavaScript 并没有其他基于类的语言所定义的“方法”。在 JavaScript 里,任何函数都可以添加到对象上作为对象的属性。函数的继承与其他的属性继承没有差别。
继承意味着复制操作,在Java和C#中,继承是完全复制生成新的对象。然而 JavaScript 默认并不会复制对象的属性,相反,JavaScript 只是在两个对象之间创建一个关联,这样,一个对象就可以通过委托访问另一个对象的属性和函数,所以与其叫继承,委托的说法反而更准确些。
结论
在编写使用它的复杂代码之前,理解原型继承模型是至关重要的。此外,请注意代码中原型链的长度,并在必要时将其分解,以避免可能的性能问题。此外,原生原型不应该被扩展,除非它是为了与新的JavaScript特性兼容。
参考文档: https://www.jb51.net/article/123976.htm
https://github.com/mqyqingfeng/Blog/issues/2
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
JavaScript进阶之原型链的更多相关文章
- 对Javascript 类、原型链、继承的理解
一.序言 和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...
- 图解JavaScript中的原型链
转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...
- javascript进阶-《原型对象和原型链》
原创发布 by @一像素 2015.12 在Javascript中,万物皆对象,但对象也有区别,大致可以分为两类,即:普通对象Object 和 函数对象Function. 一般而言,通过new Fun ...
- javaScript里的原型链
原型对象也是普通的对象,是对象一个自带隐式的__proto__属性,原型也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链.原型链是由一些用来继承和共享属性的对象组成的( ...
- JavaScript继承与原型链
对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念( ES6 新增了c ...
- 一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结
1. JavaScript内置对象 所谓的内置对象 指的是:JavaScript本身就自己有的对象 可以直接拿来就用.例如Array String 等等.JavaScript一共有12内置对象 ...
- 前端入门15-JavaScript进阶之原型链
声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...
- JavaScript中的原型链原理
工作中经常解除到prototype的概念,一开始错误的认为prototype是对象的原型链,其实prototype只能算是JavaScript开放出来的原型链接口,真正的原型链概念应该是__proto ...
- Javascript 组合继承 原型链继承 寄生继承
Javascript继承通常有三种方式. 第一种:组合式继承: function SuperType(name) { this.name = name; this.colors = ["re ...
随机推荐
- 网线直连Window和Ubuntu
找根网线直接连接两台电脑. 然后设置对应的网络到相同的网关和Mask下面. 检测能否ping通就可以直连了. Ubuntu设置网络后可在IP设置界面里设置Route, 选择直连网线仅用于连接 ...
- SpringBoot学习笔记(6)----SpringBoot中使用Servlet,Filter,Listener的三种方式
在一般的运用开发中Controller已经大部分都能够实现了,但是也不排除需要自己实现Servlet,Filter,Listener的方式,SpringBoot提供了三种实现方式. 1. 使用Bean ...
- 优动漫PAINT绘制紫阳花教程
紫阳花是插画.漫画很常见的绘画画材.这个教程非常好懂.而且很方便就能绘制出漂亮的效果.因为这种花一个月内能变化三种颜色,故而人们赋予它的花语是善变.背叛. 教程是简单,呃.... 没有优动漫PAINT ...
- 洛谷P2756 飞行员配对方案问题 网络流_二分图
Code: #include<cstdio> #include<queue> #include<vector> #include<cstring> #i ...
- vue 所有的路由跳转加一个统一参数
需求是什么 所有的路由跳转加一个统一的参数 实现方式 先深入理解一下router的全局前置守卫 router.beforeEach((to, from, next) => { const que ...
- 页面加载完成触发input[type="file"]控件问题
由于浏览器厂家的限制,不同的浏览器不开放页面加载完成就允许触发input[type="file"]控件 测试 Chrome .火狐 .IE .微信客户端QQ =>桌面端: C ...
- 在学校机房联想硬盘保护下安装Linux,并配置锐捷客户端
最近几天一直在机房里刷题,空调开着非常舒服.但是机房电脑里全是windows系统,不太好用,挺膈应人的. 一直打算换个系统,刚才终于搞定网络问题了,以后用电脑就可以爽到了. 联想硬盘保护系统下u盘安装 ...
- luogu P2041 分裂游戏(结论题)
题意 题解 一开始理解错题意了.以为这题不可解.. 其实这题当n>=3时都是无解的 然后n=1,2时的解都给出来了. 推荐一个博客的证明 #include<iostream> #in ...
- 大O时间复杂度
大O表示法指出了在最糟情况下的运行时间.比较操作数,指出了算法运行时间的增速 常见的大O运行时间 O(logn):也叫对数时间,包括二分查找 O(n):也叫线性时间,包括简单查找 O(nlogn):包 ...
- Codeforces Round #249 (Div. 2) (模拟)
C. Cardiogram time limit per test 1 second memory limit per test 256 megabytes input standard input ...