js原型和原型链,以及__proto__、prototype属性
__proto__和prototype属性:
1、__proto__属性:
在JS里,万物皆对象(函数是对象、原型也是对象...)。对象都具有属性__proto__,这个属性会指向该对象的原型。
2、prototype属性:
除此之外,函数(Function)也是对象,而且函数除了上面说的__proto__这个属性外,还有额外的一个prototype属性。函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型,也就是下面例子中的 person1 和 person2 的原型。
那什么是原型呢?你可以这样理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型"继承"属性。
原型链:
1、函数和原型关系:
我们先使用构造函数创建一个对象,Person 就是一个构造函数(注:首字母大写只是约定俗成,不大写照样可以),我们使用 new 创建了两个实例对象 person1和persion2。
function Person() {
}
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
让我们用一张图表示构造函数和实例原型之间的关系:
在这张图中我们用 Object.prototype 表示实例原型。(构造)函数有一个prototype属性,指向了实例原型。
2、实例和原型关系:
那么我们该怎么表示实例与实例原型,也就是 person 和 Person.prototype 之间的关系呢?很自然,我们知道没有对象都有__proto__属性,而且他指向的就是对象的原型。
function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
3、构造函数:
既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢?指向实例倒是没有,因为一个构造函数可以生成多个实例,但是原型指向构造函数倒是有的,如下代码可以验证
function Person() {
}
console.log(Person === Person.prototype.constructor); // true
讲到这里,我们知道了函数、对象实例和原型之间的关系了,他们是通过prototype和__proto__两个属性联系起来的。如下图
4、原型链:
原型链就是依托__proto__和prototype连接起来的一个原型链条,我们先看个例子
function Person() {
}
// 原型属性
Person.prototype.name = ‘Jiang’
var person1 = new Person()
// 实例属性
person1.name = ‘J’
console.log(person1.name) // J
上面代码中在实例属性和原型属性都有一个名为name的属性,但是最后输出来的是实例属性上的值。
当我们读取一个属性的时候,如果在实例属性上找到了,就读取它,不会管原型属性上是否还有相同的属性,这其实就是属性屏蔽,即当实例属性和原型属性拥有相同名字的时候,实例属性会屏蔽原型属性,记住只是屏蔽,不会修改,原型属性那个值还在;但是如果在实例属性上没有找到的话,就会在实例的原型上去找,如果原型上还没有,就继续到原型的原型上去找,直到尽头。
这个尽头是啥?由于原型也是对象,所以也会有__proto__属性,也就是原型的原型;最后就可以找到Object.prototype这个大boss,所有原型对象都是Object构造函数生成的(Object.prototype值为null)。正是因为所有的原型最终都会指向Object.prototype,所以对象的很多方法其实都是继承于此,比如toString()、valueOf(),前面用到的hasOwnProperty,甚至是.constructor、proto
补充:一些常用方法:
1)检查对象是否有该属性:
function Person() {
}
var person1 = new Person()
// 实例属性
person1.name = ‘J’
person1.hasOwnProperty(‘name’) // true
注:hasOwnProperty属性只有存在于实例中才会返回true
2)in则会遍历所有属性,不管是实例上的,还是原型上的:
function Person() {
}
Person.prototype.age = ‘100’
var person1 = new Person()
person1.name = ‘J’
'name' in person1 // true
'age' in person1 // true
for (var prop in person1) {
console.log(prop) // name age
}
---------------------
作者:赶路人儿
来源:CSDN
原文:https://blog.csdn.net/liuxiao723846/article/details/81984357
js原型和原型链,以及__proto__、prototype属性的更多相关文章
- 对js原型对象、实例化对象及prototype属性的一些见解
什么是原型对象? 请看下面的代码,我们以各种姿势,创建了几个方法! function fn1() { } var fn2 = function () { } var fn3 = new Functio ...
- JavaScript OOP(三):prototype原型对象(即构造函数的prototype属性)
通过构造函数生成的实例化对象,无法共享属性或方法(即每个实例化对象上都有构造函数中的属性和方法):造成了一定的资源浪费 function Obj(name,age){ this.name=name; ...
- JS构造函数内的方法与构造函数prototype属性上方法的对比
本文的目的是让大家理解什么情况下把函数的方法写在JavaScript的构造函数上,什么时候把方法写在函数的 prototype 属性上;以及这样做的好处. 为了阅读方便,我们约定一下:把方法写在构造函 ...
- JavaScript原型和原型链( prototype 与 __proto__ )
一.函数对象 所有引用类型(函数.数组.对象)都拥有__proto__属性(隐式原型) 所有函数拥有 prototype 属性(显式原型)(仅限函数) 原型对象:拥有 prototype 属性的对象, ...
- 总结一下js的原型和原型链
最近学习了js的面向对象编程,原型和原型链这块是个难点,理解的不是很透彻,这里搜集了一些这方面的资料,以备复习所用 一. 原型与构造函数 Js所有的函数都有一个prototype属性,这个属性引用了一 ...
- JS原型、原型链深入理解
原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 一.初识原 ...
- Js 原型,原型链
原型,原型链 原型:在JavaScript中原型是一个prototype对象,用于表示类型之间的关系. 原型链:JavaScript万物都是对象,对象和对象之间也有关系,并不是孤立存在的.对象之间的继 ...
- 理解js中的原型链
对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 关于原型 在JavaScript中,原型也是一个对象,通过原型可以实现对象的属性继承 ...
- 对于js原型和原型链继承的简单理解(第一种,原型链继承)
原型是js中的难点加重点,也是前端面试官最爱问的问题之一,因为面试官可以通过被面试者对原型的理解.来判断被面试者对js的熟悉程度. 原型的定义 Js所有的函数都有一个prototype属性,这个属性引 ...
- js原型,原型链的理解
1.所有引用类型(函数.数组.对象)都拥有_proto_属性(隐式原型) 2.所有函数拥有prototype属性(显式原型)(仅限函数) 3.原型对象:拥有prototype属性的对象,在定义函数时就 ...
随机推荐
- 一小段 Dapper 的简单示例
关于 Dapper 的介绍,请参考:Dapper - 一款轻量级对象关系映射(ORM)组件,DotNet 下 using System; using System.Collections.Generi ...
- 一致性hash应用-分表扩容
之前给项目里的一个5000多万的表做了水平分表,暂时容量还够,用的根据id一致性hash分了32个表,每个表大概百来万数据.虽然还不需要扩容,但是准备写个demo后续如果需要扩容可以参考 hash方法 ...
- LaTex语法
排版数学公式是TeX系统设计的初衷,它在LaTeX中占有特殊地位,也是LaTeX最为人所称道的功能之一.基于对MathType排版效果的不满意,以及对公式进行检索的需求,我们使用LaTeX输入数学公式 ...
- Swagger实例分享(VS+WebApi+Swashbuckle)
Swagger实例分享(VS+WebApi+Swashbuckle) Swagger可以很方便的为发布的WebApi自动生成优雅的文档,不需额外自己编写,只需为项目配置好,是一个很好用的工具,做一个简 ...
- 记录微信支付开发中的小经验(errcode = 40163; errmsg = "code been used")
今天上午客户提出问题,看了一下报错截图,应该是我更新版本时少传了一个参数,导致后续报错, 心里想着小问题,直接生产环境添加一下就行了,于是就为了我这一上午的悲剧埋下了伏笔 十分自信的把页面中的代码添加 ...
- Java学习——日期类
Java学习——日期类 摘要:本文主要记录了Java开发中用到的和日期有关的类以及对日期的操作. 部分内容来自以下博客: https://www.cnblogs.com/talk/p/2680591. ...
- Vue笔记3
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- vue实现word,pdf文件的导出功能
vue实现word或pdf文档导出的功能,我的项目是:后端返回一个文档流(下图),然后前端对文档流做处理进行下载,代码如下: import axios from 'axios'; axios.get( ...
- a标使用window.open()方法
<a href="javascript:window.open('../Left_B/L_Gong_gao_Index', 'TencentLogin', 'width=1920px, ...
- 技能篇丨FineCMS 5.0.10 多个漏洞详细分析
今天是一篇关于技能提升的文章,文章中的CMS是FineCMS,版本是5.0.10版本的几个漏洞分析,主要内容是介绍漏洞修补前和修补后的分析过程,帮助大家快速掌握该技能. 注:篇幅较长,阅读用时约7分钟 ...