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语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...
随机推荐
- Material Designer的低版本兼容实现(一)—— 简介 & 目录
很长一段时间没写东西了,其实是因为最近在研究Material Designer这个东西,熬夜熬的身体也不是很好了.所以就偷懒没写东西,这回开的这个系列文章是讲如何将Material Designer在 ...
- 详细解释如何通过Android自带的方式来实现图片的裁剪——原理分析+解决方案
我们很多时候需要进行图片的裁剪,其实这个功能在android系统中已经有一套解决方案了,虽然界面和效果并不是很优秀但功能毫无疑问是完美实现了.至于,不用自带的方案怎么做自定义,这个就是后话了.本篇主要 ...
- Log Shipping搭建
1. 概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据库”内的事务日志备份发送到单独“辅助服务器”实例上的一个或多个“辅助数据库”.事务日志备份分别应用于每个辅助 ...
- cesium js学习一加载三维模型【转】
http://blog.csdn.net/tangyajun_168/article/details/50936698 最近项目中用到室外三维模型与室内三维地图交互,室外三维模型的加载我们采用了ces ...
- [leetcode]Pascal's Triangle @ Python
原题地址:https://oj.leetcode.com/problems/pascals-triangle/ 题意: Given numRows, generate the first numRow ...
- adb 环境配置 常用命令 总结
配置环境变量 右键我的电脑 -> 属性 -> 高级 -> 环境变量 -> Path 在Path中添加Android SDK安装路径中 adb.exe 的路径,例如[\sdk\p ...
- Mahout源码目录说明
http://www.cnblogs.com/dlts26/archive/2011/08/23/2150230.html mahout项目是由多个子项目组成的,各子项目分别位于源码的不同目录下,下面 ...
- ssh tunnel
https://peppoj.net/2012/10/tunnel-http-traffic-encrypted-using-polipo-and-ssh/ --------------------- ...
- Spring(十二):IOC容器中Bean的生命周期方法
IOC容器中Bean的生命周期方法 1)Spring IOC容器可以管理Bean的声明周期,Spring允许在Bean生命周期的特定点执行定制的任务. 2)Spring IOC容器对Bean的生命周期 ...
- redis信息相关集群
转: http://www.runoob.com/redis/redis-install.html //redis的安装与运维相关 http://zhou123.blog.51cto.com/4355 ...