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

prototypelength是每一个函数类型自带的两个属性,而其它非函数类型并没有,这一点之所以比较容易被忽略或误解,是因为所有类型的构造函数本身也是函数,所以它们自带了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中的所有对象(undefinednull等特殊情况除外)都有一个内置的[[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__的更多相关文章

  1. js原型链prototype与__proto__以及new表达式

    对象模型的细节 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model

  2. JavaScript原型链:prototype与__proto__

    title: 'JavaScript原型链:prototype与__proto__' toc: false date: 2018-09-04 11:16:54 主要看了这一篇,讲解的很清晰,最主要的一 ...

  3. JS原型链

    JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...

  4. 深入分析JS原型链以及为什么不能在原型链上使用对象

    在刚刚接触JS原型链的时候都会接触到一个熟悉的名词:prototype:如果你曾经深入过prototype,你会接触到另一个名词:__proto__(注意:两边各有两条下划线,不是一条).以下将会围绕 ...

  5. JS 原型链图形详解

    JS原型链 这篇文章是「深入ECMA-262-3」系列的一个概览和摘要.每个部分都包含了对应章节的链接,所以你可以阅读它们以便对其有更深的理解. 对象 ECMAScript做为一个高度抽象的面向对象语 ...

  6. js 原型链和继承(转)

    在理解继承之前,需要知道 js 的三个东西: 什么是 JS 原型链 this 的值到底是什么 JS 的 new 到底是干什么的 1. 什么是 JS 原型链? 我们知道 JS 有对象,比如 var ob ...

  7. 一张图看懂 JS 原型链

    JS 原型链,画了张图,终于理清楚各种关系有木有 写在最后: __proto__是每个对象都有的一个属性,而prototype是函数才会有的属性!!! function Person() { } 是函 ...

  8. 简单粗暴地理解js原型链–js面向对象编程

    简单粗暴地理解js原型链–js面向对象编程 作者:茄果 链接:http://www.cnblogs.com/qieguo/archive/2016/05/03/5451626.html 原型链理解起来 ...

  9. JS原型链与继承别再被问倒了

    原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...

随机推荐

  1. Java移位运算符详解实例——左移位运算符>>、带符号的右移位运算符>>

    移位运算符也针对二进制的“位”,它主要包括:左移位运算符(<<).右移位运算符(>>>).带符号的右移位运算符(>>). 1.左移运算符左移运算符用“< ...

  2. HTML5+Java(Spring下) 拍照上传图片

    使用支持html5的浏览器,找个有摄像头,再建一个文件接收base64字串的图片然后保存就哦了 <html> <head runat="ReYo-Server"& ...

  3. SharePoint 应用程序页匿名

    前言 最近,有朋友问开发应用程序页,都是需要先登录再访问,无法开发匿名的应用程序页. 解决方法 其实,SharePoint帮我们提供了匿名访问的应用程序页的方法,只是和普通应用程序页继承的基类不一样, ...

  4. VS2010Web默认的浏览器设置和VS里调试JavaScript代码的设置

    前言 重装系统后,VS调用的Web浏览器不是IE了,VS调式不了JavaScript代码了.这两天一直在试终于搞定了.这里查找的问题当然主要是VS里面调式JavaScript代码了. 第一种方式设置V ...

  5. 《Netty权威指南》

    <Netty权威指南> 基本信息 作者: 李林锋 出版社:电子工业出版社 ISBN:9787121233432 上架时间:2014-5-29 出版日期:2014 年6月 开本:16开 页码 ...

  6. 禁止MT在公式后面自动添加一个空格

    开始 > 运行,或者win+R,然后输入 regedit,打开注册表编辑器.展开到HKEY_CURRENT_USER\Software\Design Science\DSMT6\WordComm ...

  7. Maven 搭建spring boot多模块项目(附源码),亲测可以,感谢原创

    原创地址:https://segmentfault.com/a/1190000005020589 我的DEMO码云地址,持续添加新功能: https://gitee.com/itbase/Spring ...

  8. Rotate Image leetcode java

    题目: You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwis ...

  9. Eclipse添加tomcat服务器以及解决404的问题

    Eclipse JavaEE IDE添加tomcat服务器 1. 先做准备工作,首先下载工具 点击下方链接下载     1) Tomcat v7.0     2) Eclipse IDE for Ja ...

  10. NLP领域的ImageNet时代到来:词嵌入「已死」,语言模型当立

    http://3g.163.com/all/article/DM995J240511AQHO.html 选自the Gradient 作者:Sebastian Ruder 机器之心编译 计算机视觉领域 ...