js 原型链 prototype __proto__
1、说明
函数(Function)才有prototype属性,对象(除Object)拥有__proto__。
2、prototype与__proto__区别


示例:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>prototype与__proto__区别</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
var a = {};
console.log(a.prototype); //undefined
console.log(a.__proto__); //Object {} var b = function() {}
console.log(b.prototype); //b {}
console.log(b.__proto__); //function() {}
</script>
</body> </html>
控制台输出:

(3)__proto__指向

示例:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>__proto__指向</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
/*1、字面量方式*/
var a = {};
console.log(a.__proto__); //Object {} console.log(a.__proto__ === a.constructor.prototype); //true /*2、构造器方式*/
var A = function() {};
var b = new A();
console.log(b.__proto__); //A {} console.log(b.__proto__ === b.constructor.prototype); //true /*3、Object.create()方式*/
var a1 = {
a: 1
}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1} console.log(a2.__proto__ === a2.constructor.prototype); //false(此处即为图1中的例外情况)
</script>
</body> </html>
控制台输出:

(4)原型链
(1)是__proto__指向的一条指针链!
(2)查找属性时,首先先查找自身属性,找不到的话,在查找原型链上的属性。但是不会查找自身的prototype属性。
示例代码:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>属性查找</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
Function.prototype.age = 20;
let b = function() {}
b.prototype.age = 10;
console.log(b.age)//输出20
</script>
</body> </html>

示例:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>原型链</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
var A = function() {};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null
</script>
</body> </html>
(5)prototype
prototype和length是每一个函数类型自带的两个属性,而其它非函数类型并没有,这一点之所以比较容易被忽略或误解,是因为所有类型的构造函数本身也是函数,所以它们自带了prototype属性:
示例:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>prototype</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
console.log(Object.prototype); //=> {} console.log(Function.prototype); //=> [Function: Empty] console.log(String.prototype); //=> [String: '']
</script>
</body> </html>
除了prototype之外,Js中的所有对象(undefined、null等特殊情况除外)都有一个内置的[[Prototype]]属性,指向它“父类”的prototype,这个内置属性在ECMA标准中并没有给出明确的获取方式,但是许多Js的实现(如Node、大部分浏览器等)都提供了一个__proto__属性来指代这一[[Prototype]],我们通过下面的例子来说明实例中的__proto__是如何指向构造函数的prototype的:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>prototype与__proto__</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
var Person = function() {}; Person.prototype.type = 'Person'; Person.prototype.maxAge = 100; var p = new Person(); p.name = 'rainy'; Person.prototype.constructor === Person; //=> true p.__proto__ === Person.prototype; //=> true console.log(p.prototype); //=> undefined
console.log(p.maxAge); //100
console.log(p.__proto__.maxAge); //100
console.log(p.name); //rainy
console.log(p.__proto__.name); //undefined
</script>
</body> </html>
图示:

Person是一个函数类型的变量,因此自带了prototype属性,prototype指向中的Person.prototype对象。Person.prototype.constructor又指向Person本身;通过new关键字生成的Person类的实例p1,通过__proto__属性指向了Person的原型。这里的__proto__只是为了说明实例p1在内部实现的时候与父类之间存在的关联(指向父类的原型),在实际操作过程中实例可以直接通过.获取父类原型中的属性,从而实现了继承的功能。
(6)原型链
示例代码:
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>prototype与__proto__</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
var Obj = function() {}; var o = new Obj(); o.__proto__ === Obj.prototype; //=> true o.__proto__.constructor === Obj; //=> true Obj.__proto__ === Function.prototype; //=> true Obj.__proto__.constructor === Function; //=> true Function.__proto__ === Function.prototype; //=> true Object.__proto__ === Object.prototype; //=> false Object.__proto__ === Function.prototype; //=> true Function.__proto__.constructor === Function; //=> true Function.__proto__.__proto__; //=> {} Function.__proto__.__proto__ === o.__proto__.__proto__; //=> true o.__proto__.__proto__.__proto__ === null; //=> true
</script>
</body> </html>
(7)null与undefined
null与undefined 无原型
//报错
console.log(Object.getPrototypeOf(undefined))
//报错
console.log(Object.getPrototypeOf(null))

从上面的例子和图解可以看出,prototype对象也有__proto__属性,向上追溯一直到null。
(8)原型链的遍历过程(一直到null)
<!DOCTYPE html>
<html lang="zh"> <head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>原型链的遍历过程</title>
</head> <body>
<script src="https://cdn.bootcss.com/lodash.js/4.17.10/lodash.min.js"></script>
<script type="text/javascript">
let a = 1
console.log(a.__proto__ === Number.prototype) //true
console.log(Number.__proto__ === Function.prototype) //true
console.log(Function.__proto__ === Function.prototype) //true
console.log(Function.__proto__.__proto__ === Object.prototype) //true
console.log(Function.__proto__.__proto__.__proto__)
</script>
</body> </html>
(9)获取原型对象
Object.getPrototypeOf(object)
(10)原型上可遍历的属性

__proto__ 隐式原型 prototype显示原型

js 原型链 prototype __proto__的更多相关文章
- js原型链prototype与__proto__以及new表达式
对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model
- JavaScript原型链:prototype与__proto__
title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...
- JS原型链
JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...
- 深入分析JS原型链以及为什么不能在原型链上使用对象
在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...
- JS 原型链图形详解
JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...
- js 原型链和继承(转)
在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的 new 到底是干什么的 1. 什么是 JS 原型链? 我们知道 JS 有对象,比如 var ob ...
- 一张图看懂 JS 原型链
JS 原型链,画了张图,终于理清楚各种关系有木有 写在最后: __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!! function Person() { } 是函 ...
- 简单粗暴地理解js原型链–js面向对象编程
简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...
- JS原型链与继承别再被问倒了
原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...
随机推荐
- 使用node-webkit实现打包工具的小结
之前一直使用的hta在开发工具,最近转到node-webkit上了,对比一下二者的优劣势.hta单个文件,体积较小,但有兼容性的问题(兼容ie6.7.8就行了,也还好),node-webkit使用we ...
- [Web 前端] webstorm 快速搭建react项目
cp from : https://blog.csdn.net/qq_39207948/article/details/79467144 前端新手如何安装webstorm ,初步搭建react项目 下 ...
- [Web 前端] CSS篇之 4. position 和 display 的取值和各自的意思和用法
讲一讲CSS的position/float/display都有哪些取值,它们相互叠加时的行为都是什么? 列出display的值,说明他们的作用.position的值, relative和absolu ...
- 伯努利分布、二项分布、Beta分布、多项分布和Dirichlet分布与他们之间的关系,以及在LDA中的应用
在看LDA的时候,遇到的数学公式分布有些多,因此在这里总结一下思路. 一.伯努利试验.伯努利过程与伯努利分布 先说一下什么是伯努利试验: 维基百科伯努利试验中: 伯努利试验(Bernoulli tri ...
- [转]小心PHP的类定义顺序与继承的问题
FROM : http://www.pakey.net/blog/php-class-shunxu.html 以下代码的运行环境均为PHP5.3.11先来看一段代码 <?php class A ...
- #incldue<cctype>函数系列
#include <cctype>的函数 c++中应该是#include <cctype> c中应该是#include <ctype.h> 以下为字符函数库中常用的 ...
- java的反射机制浅谈(转)
原文链接:java的反射机制浅谈 一.java的反射机制浅谈 1.何谓反射机制 根据网文,java中的反射机制可以如此定义: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...
- Log Shipping搭建
1. 概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据库”内的事务日志备份发送到单独“辅助服务器”实例上的一个或多个“辅助数据库”.事务日志备份分别应用于每个辅助 ...
- 一个可用来记录Isilon各个节点的CPU,网络,磁盘性能的命令
通过查看命令isi statistics system的帮助信息,拼出了下面的命令. isi statistics system list --nodes=all --degraded --forma ...
- iOS开发-iOS8地理位置定位
现在的App基本上都有定位功能,旅游网站根据定位推荐旅游景点,新闻App通过地理位置推荐当地新闻,社交类的App通过位置交友,iOS中实现以上功能需要一个核心的框架CoreLocation,框架提供了 ...