275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法
1、所有函数都有一个特别的属性
prototype
: 显式原型属性 【普通构造函数的实例对象没有prototype 属性,构造函数有__proto__属性,原型对象有__proto__属性 】
2、函数的prototype属性(图)
- 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象) 【即Object实例对象 {}】
- 原型对象中有一个属性constructor, 它指向函数对象 【相互引用】
3、给原型对象添加属性(一般都是方法)
- 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
4、所有实例对象都有一个特别的属性
__proto__
: 隐式原型属性
5、显式原型与隐式原型的关系
- 函数的prototype: 定义函数时,被自动赋值, 值默认为{}, 即用为原型对象
- 实例对象的__proto__: 在创建实例对象时,被自动添加, 并赋值为构造函数的prototype值
- 原型对象,即为当前实例对象的父对象
6、原型链 【隐式原型链】
- 所有的实例对象都有__proto__属性, 它指向的就是原型对象
- 这样通过__proto__属性就形成了一个链的结构 ----> 原型链
- 当查找对象内部的属性/方法时, js引擎自动沿着这个原型链查找,找到返回,如果最终没找到, 返回undefined
- 作用: 查找对象的属性(方法) 【作用域:查找变量。】
- 当给对象属性赋值时,不会使用原型链, 而只是在当前对象中进行操作
- Object的原型对象是原型链尽头 【Object.prototype是实例对象,但不是一般的实例对象,它的值是null,不指向任何对象,所以 console.log(Object.prototype instanceof Object) 的值是false ,console.log(Object.prototype.proto) // null 】
- 普通/一般的函数的原型对象都是Object的实例对象。
7、构造函数/原型/实例对象的关系(图解)
8、构造函数/原型/实例对象的关系2(图解)
补充:构造函数可以 new 函数名.方法() 调用
<!DOCTYPE html>
<html lang="en">
<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>构造函数可以 new 函数名.方法()调用</title>
</head>
<body>
</body>
</html>
<script>
function Fun(age) {
this.age = age
this.setAge = function(newAge) {
this.age = newAge
console.log(this.age);
}
}
console.log(Fun.prototype); // {constructor: ƒ}
Fun(0).setAge(111) // 必须要加new,new才能创建实例对象,否则报错,Cannot read property 'setAge' of undefined
let f1 = new Fun(11)
new Fun(22).setAge(33); // 33
(new Fun(22)).setAge(44) // 44
console.log(Fun.prototype); // {constructor: ƒ}
Fun.prototype.test = function() {
console.log('哈哈');
}
f1.setAge(55) // 55
f1.test() // 哈哈
</script>
原型(prototype)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01_原型(prototype)</title>
</head>
<body>
<!--
1. 函数的prototype属性(图)
* 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
* 原型对象中有一个属性constructor, 它指向函数对象 【相互引用】
2. 给原型对象添加属性(一般都是方法)
* 作用: 函数的所有实例对象自动拥有原型中的属性(方法)
-->
<script type="text/javascript">
// 每个函数都有一个prototype属性, 它默认指向一个Object空对象(即称为: 原型对象)
console.log(Date.prototype, typeof Date.prototype)
function Fun() { //alt + shift +r(重命名rename)
}
console.log(Fun.prototype) // 默认指向一个Object空对象(没有我们的属性)
// 原型对象中有一个属性constructor, 它指向函数对象
console.log(Date.prototype.constructor === Date)
console.log(Fun.prototype.constructor === Fun)
//给原型对象添加属性(一般是方法) ===>实例对象可以访问
Fun.prototype.test = function() {
console.log('test()')
}
var fun = new Fun()
fun.test()
</script>
</body>
</html>
显式原型与隐式原型
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02_显式原型与隐式原型</title>
</head>
<body>
<!--
1. 每个函数function都有一个prototype,即显式原型(属性)
2. 每个实例对象都有一个__proto__,可称为隐式原型(属性)
3. 对象的隐式原型的值为其对应构造函数的显式原型的值
4. 内存结构(图)
5. 总结:
* 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
* 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
* 程序员能直接操作显式原型, 但不能直接操作隐式原型(ES6之前)
-->
<script type="text/javascript">
//定义构造函数
function Fn() { // 内部语句: this.prototype = {}
}
// 1. 每个函数function都有一个prototype,即显式原型属性, 默认指向一个空的Object对象
console.log(Fn.prototype)
// 2. 每个实例对象都有一个__proto__,可称为隐式原型
//创建实例对象
var fn = new Fn() // 内部语句: this.__proto__ = Fn.prototype
console.log(fn.__proto__)
// 3. 对象的隐式原型的值为其对应构造函数的显式原型的值
console.log(Fn.prototype===fn.__proto__) // true
//给原型添加方法
Fn.prototype.test = function () {
console.log('test()')
}
//通过实例调用原型的方法
fn.test()
</script>
</body>
</html>
原型链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>03_原型链</title>
</head>
<body>
<!--
1. 原型链(图解)
* 访问一个对象的属性时,
* 先在自身属性中查找,找到返回
* 如果没有, 再沿着__proto__这条链向上查找, 找到返回
* 如果最终没找到, 返回undefined
* 别名: 隐式原型链
* 作用: 查找对象的属性(方法) 【作用域:查找变量。】
2. 构造函数/原型/实体对象的关系(图解)
3. 构造函数/原型/实体对象的关系2(图解)
-->
<script type="text/javascript">
// console.log(Object)
//console.log(Object.prototype)
console.log(Object.prototype.__proto__) // null
function Fn() {
this.test1 = function() {
console.log('test1()') // test1()
}
}
// 对象就只有一个/一份,所以这句代码虽然在添加test2方法前,但是依然会输出test2
console.log(Fn.prototype) // {constructor: ƒ}
Fn.prototype.test2 = function() {
console.log('test2()') // test2()
}
var fn = new Fn();
fn.test1();
fn.test2();
console.log(fn.toString()); // [object Object]
console.log(fn.test3); // undefined
// fn.test3() // 报错
// 1. 函数的显式原型指向的对象,默认是空Object实例对象(但Object不满足)
console.log(Fn.prototype instanceof Object) // true
console.log(Object.prototype instanceof Object) // false
console.log(Function.prototype instanceof Object) // true
// 2. 所有函数都是Function的实例(包含Function)
console.log(Function.__proto__ === Function.prototype) // true
// 3. Object的原型对象是原型链尽头
console.log(Object.prototype.__proto__) // null
</script>
</body>
</html>
原型链_属性问题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_原型链_属性问题</title>
</head>
<body>
<!--
1. 读取对象的属性值时: 会自动到原型链中查找
2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上
-->
<script type="text/javascript">
function Fn() {
}
Fn.prototype.a = 'xxx'
var fn1 = new Fn()
console.log(fn1.a, fn1) // xxx Fn {}
var fn2 = new Fn()
fn2.a = 'yyy' // 给fn2添加属性a,并赋值,不会去查找原型链
console.log(fn1.a, fn2.a, fn2) // (1)xxx yyy Fn {a: "yyy"};(2)fn2.a 时,先到自己内部查找,找不到,再去查找原型链
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.setName = function(name) {
this.name = name
}
var p1 = new Person('Tom', 12)
p1.setName('Bob')
console.log(p1) // Person {name: "Bob", age: 12}
var p2 = new Person('Jack', 12)
p2.setName('Cat')
console.log(p2) // Person {name: "Cat", age: 12}
console.log(p1.__proto__ === p2.__proto__) // true,都是指向Person.prototype
</script>
</body>
</html>
275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法的更多相关文章
- 继承:《原型和原型链(prototype 属性使您有能力向对象添加属性和方法。)》
二. 原型对象 在JavaScript 中,每当定义一个对象(函数)时候,对象中都会包含一些预定义的属性.其中函数对象的一个属性就是原型对象 prototype.注:普通对象没有prototype ...
- JavaScript面向对象(二)——成员属性、静态属性、原型属性与JS原型链
前 言 JRedu 上一篇博客中,我们介绍了JS中的面向对象,并详细的解释了this的指向问题.本篇博客,我们继续来学习JS的面向对象.来深入理解一下JavaScript OOP中的成员属性/方 ...
- JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。
回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...
- 原型链继承中的prototype、__proto__和constructor的关系
前不久写了有关原型链中prototype.__proto__和constructor的关系的理解,这篇文章说说在原型链继承中的prototype.__proto__和constructor的关系. 通 ...
- 为什么Object.prototype在Function的原型链上与Function.prototype在Object的原型链上都为true
关于javascript的原型链有一个问题我一直很疑惑:为什么 Function instanceof Object 与 Object instanceof Function都为true呢? Func ...
- 对原型链的理解?prototype上都有哪些属性?
在js里,继承机制是原型继承.继承的起点是 对象的原型(Object prototype). 一切皆为对象,只要是对象,就会有 proto 属性,该属性存储了指向其构造的指针. Object prot ...
- js原型对象中属性被覆盖(1)
/** *@author 程无衣 *@description 关于在原型对象中属性被覆盖 */ function Person(){} Person.prototy ...
- js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。
js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法. function ClassA(sColor) { this.color = sColor; } Class ...
- JavaScript 中实现继承的方式(列举3种在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。)
第一种:对象冒充 function ClassA(sColor) { this.color = sColor; this.sayColor = function () { alert(this.col ...
随机推荐
- js中map和filter方法,以及search方法
链接:https://blog.51cto.com/11871779/2126561 search方法: 介绍: search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符 ...
- [爬坑记录] Qt 代码卡住 不发信号 不触发槽
先让我激动一会儿 [捂脸] 最近在用Qt做个程序 用来参加比赛 期间总共遇到两次如标题的问题 也即是 莫名其妙的不触发槽函数了 而且原因也不一样 {先说明 我学习Qt依旧只是入门级 也许入不了大佬法眼 ...
- 项目出现红色感叹号, pom.xml并出错
问题描述: eclipse出现红色感叹号,pom.xml 文件也报错 但没有提示具体是那里出错了. 打开 Java Build Path 找到 Librarices 你在看到 Maven Dep ...
- 每天进步一点点------入门视频采集与处理(显示YUV数据)
做视频采集与处理,自然少不了要学会分析YUV数据.因为从采集的角度来说,一般的视频采集芯片输出的码流一般都是YUV数据流的形式,而从视频处理(例如H.264.MPEG视频编解码)的角度来说,也是在原始 ...
- dubbo+zookeeper搭建笔记
参考博客: http://blog.csdn.net/u013142781/article/details/50396621#reply http://blog.csdn.net/u013142781 ...
- The Preliminary Contest for ICPC Asia Xuzhou 2019 J Random Access Iterator (树形DP)
每次循环向下寻找孩子时,随机选取一个孩子,设dp[u]为从u出发,不能得出正确答案的概率,则从u出发,走一次的情况下不能得出正确答案的概率是 P = (dp[v1]+dp[v2]+dp[v3]+--d ...
- c++写入注册表
一.说明: 注册表是Windows重要组成部分,注册表记录了大量有关电脑软硬件的信息.注册表中的值通过其名称标识.值名称由与键名相同的字符组成.值本身可以是字符串.二进制数据或者是32位无符 ...
- C语言:求n(n<10000)以内的所有四叶玫瑰数。-将字符串s1和s2合并形成新的字符串s3,先取出1的第一个字符放入3,再取出2的第一个字符放入3,
//函数fun功能:求n(n<10000)以内的所有四叶玫瑰数并逐个存放到result所指数组中,个数作为返回值.如果一个4位整数等于其各个位数字的4次方之和,则称该数为函数返回值. #incl ...
- java 工程idea 添加依赖几种方式:
1.add jar and dependecy derictory: 2.add Libary: 点击new library 选取java: 选择libs文件夹作为library: 选择 maven ...
- 【JavaWeb+Echarts+EL表达式】用图表形式展示数据
1. Echarts环境配置 https://www.echartsjs.com/zh/download.html 选择需要的,然后等待Build完成之后,就会自动弹出下载框啦! 把下载好的js放在w ...