JS 中的原型 -- prototype、__proto__ 以及原型链
原文:
1.深入理解javascript原型和闭包——prototype原型
打开浏览器控制台,任意定义一个对象,打印出来后,会发现有最后一定有一个默认属性 “__proto__”,这是 js 的设计思路,类似于 java 中的继承。
注意:在本章中严格区分函数与对象
prototype 与 __proto__
1.区别
- 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() {}
2.__proto__ 指向谁?
- /*1、字面量方式*/
- var a = {};
- console.log(a.__proto__); //Object {}
- console.log(a.__proto__ === a.constructor.prototype); //true
- /*2、构造器方式*/
- var A = function(){};
- var a = new A();
- console.log(a.__proto__); //A {}
- console.log(a.__proto__ === a.constructor.prototype); //true
- /*3、Object.create()方式*/
- var a1 = {a:1}
- var a2 = Object.create(a1);
- console.log(a2.__proto__); //Object {a: 1}
- console.log(a.__proto__ === a.constructor.prototype); //false(此处即为图1中的例外情况)
3.原型链
- 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
prototype 属性
这个prototype的属性值是一个对象(属性的集合),默认的只有一个叫做 constructor 的属性,指向这个函数本身。如下图:
原型既然作为对象,属性的集合,不可能就只弄个constructor来玩玩,肯定可以自定义的增加许多属性。例如 Object 这个函数,该函数的prototype里面,就有好几个其他属性。
以上是 Object 的原型示意。
那么,我们自己定义的函数/对象中,可不可以进行自定义内? 答案: 可以。
- function Fn() { }
- Fn.prototype.name = '王福朋';
- Fn.prototype.getYear = function () {
- return 1988;
- };
这样做的意义在哪?
- function Fn() { }
- Fn.prototype.name = '王福朋';
- Fn.prototype.getYear = function () {
- return 1988;
- };
- var fn = new Fn();
- console.log(fn.name); // 王福朋
- console.log(fn.getYear()); // 1988
首先,定义了个空的 Fn 函数;
接着,自定义 Fn.prototype 属性;
其次,fn 对象是从 Fn 函数中 new 出来的;
因为每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象的函数的prototype(注意区分对象和函数)。即:fn.__proto__ === Fn.prototype
结论:每个对象都有一个隐藏的属性——“__proto__”,这个属性引用了创建这个对象的函数的prototype(注意区分对象和函数)。
JS 中的原型 -- prototype、__proto__ 以及原型链的更多相关文章
- Js中的对象、构造函数、原型、原型链及继承
1.对象 在传统的面向过程的程序设计中,会造成函数或变量的冗余.而JS中对象的目的是将所有的具有相同属性或行为的代码整合到一起,形成一个集合,这样就会方便我们管理,例如: var person1={ ...
- JavaScript的原型对象prototype、原型属性__proto__、原型链和constructor
先画上一个关系图: 1. 什么是prototype.__proto__.constructor? var arr = new Array; 1. __proto__是原型属性,对象特有的属性,是对象指 ...
- js中constructor和prototype
在最开始学习js的时候,我们在讲到原型链和构造函数的时候经常会有一个例子 如果我们定义函数如下: function Foo() { /* .. */ } Foo.prototype.bar = fun ...
- 转载-对js中new、prototype的理解
说明:本篇文章是搜集了数家之言,综合的结果,应向数家致谢 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/java ...
- JS中constructor与prototype关系概论
在学习JS的面向对象过程中,一直对constructor与prototype感到很迷惑,看了一些博客与书籍,觉得自己弄明白了,现在记录如下: 我们都知道,在JS中有一个function的东西. ...
- JS中使用组合构造函数模式和原型模式
创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式.构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性. 结果,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的 ...
- js 中调用 Object.prototype.toString()来检测对象的类型
1.使用toString()方法来检测对象类型 可以通过toString() 来获取每个对象的类型.为了每个对象都能通过 Object.prototype.toString() 来检测,需要以 Fun ...
- js中通过Object.prototype.toString方法----精确判断对象的类型
判断是否为函数 function isFunction(it) { return Object.prototype.toString.call(it) === '[object Func ...
- 关于JS对象原型prototype与继承,ES6的class和extends · kesheng's personal blog
传统方式:通过function关键字来定义一个对象类型 1234567891011 function People(name) { this.name = name}People.prototype. ...
- Js中关于构造函数,原型,原型链深入理解
在 ES6之前,在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但 ...
随机推荐
- pythn print格式化输出---------"%s 和 % d" 都是什么意思?
pythn print格式化输出. %r 用来做 debug 比较好,因为它会显示变量的原始数据(raw data),而其它的符号则是用来向用户显示输出的. 1. 打印字符串 print (" ...
- oracle nvl,nvl2,coalesce几个函数的区别
1.nvl(exp1,exp2)该函数是处理表达式中的空值: 假设表达式exp1是空值,则该函数返回表达式exp2的值, 假设表达式exp1没有是空值,则该函数返回表达式exp1的值. 2.nvl2( ...
- Vue.js如何在一个页面调用另一个同级页面的方法
使用场景: 页面分为header.home.footer三部分,需要在home中调用header中的方法,这两个没有相互引入 官方给出方法: 需要在展示页里调用顶部导航栏页里的方法,两者之间没有引用关 ...
- JAVA forname classnotfoundexception 错误
今日在使用Class.forName方法的时候报了错误: JAVA forname classnotfoundexception 原因是Class.forName(className);里面的clas ...
- RelativeLayout设置wrap_content无效
尊重劳动成果,转载请标明出处:http://www.cnblogs.com/tangZH/p/8419053.html 在做项目的过程中,遇到了一个奇怪的现象,我设置RelativeLayout为的宽 ...
- java线程介绍
文章讲解要点 1.线程创建几种方式2.线程常见设置方法,包括优先级.优先级休眠.停止等3.多线程间的数据交互与锁机制4.项目源码下载 线程介绍.png 一.线程创建方式 常见的线程创建方法以下三种 ...
- angular应用容器化部署
angular 应用容器化部署 Intro 我自己有做一个个人主页,虽然效果不怎么样(不懂设计的典型程序猿...),但是记录了我对于前端框架及工具的一些实践, 从开始只有一个 angularjs 制作 ...
- redis 慢日志查询
Intro 可能有一些命令需要很长时间才能在redis服务器上处理,导致请求超时. 长时间运行的命令的很少例子有 mget有大量的键,键*或写得不好的lua脚本. 可以运行通过 SlowLog 命令查 ...
- spring学习总结——高级装配学习三(Bean的作用域)
一.bean的作用域 在默认情况下,Spring应用上下文中所有bean都是作为以单例(singleton)的形式创建的.也就是说,不管给定的一个bean被注入到其他bean多少次,每次所注入的都是同 ...
- Django Linux环境下部署CentOS7+Python3+Django+uWSGI+Nginx(含Nginx返回400问题处理、防火墙管理)
本文将介绍如何在Linux系统上部署Django web项目,本次部署基于下面的架构: CentOS7+ Python3.5 + Django1.11 + uWSGI + Nginx 亲测可行!!按照 ...