原型对象 `prototype`
-  原型对象的所有属性和方法,都能被实例对象共享;
 
JavaScript 通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。

function Cat (name, color) {
this.name = name;
this.color = color;
} var cat1 = new Cat('小明', '白色'); cat1.name // '小明'
cat1.color // '白色'

构造函数缺点:

- 一个构造函数的多个实例之间,无法共享属性,从而造成对系统资源的浪费。
解决方法,就是 JavaScript 的原型对象`prototype`,因为原型对象的所有属性和方法,都能被实例对象共享。
function Cat (name, color) {
this.name = name;
}
Cat.prototype.color ="白色";
}
var cat1 = new Cat('巧克力');
var cat2 = new Cat('布丁');
cat1.color //白色
cat2.color//白色
JavaScript规定,每个函数都有一个`prototype`属性,指向一个对象。
- 对于构造函数来说,生成实例的时候,该属性会自动成为实例对象的原型。
- 实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。
function f() {}
typeof f.prototype // "object"
每个 JS 对象都有 `__proto__` 属性,这个属性可以访问到 原型(`[[prototype]]`) 内部属性。这个属性在现在来说已经不推荐直接去使用它了。

原型链

 - 任何对象,都可以充当其他对象的原型;原型对象也有自己的原型。
 - 对象到原型,再到原型的原型,一层层向上找到`Object.prototype` 形成原型链。
可以说 基本上所有对象都继承了`Object.prototype`的属性;而 `Object.prototype` 的原型是 `null`
通过 `getPrototypeOf` 方法返回参数对象原型
Object.getPrototypeOf(Object.prototype) //null
 读取对象属性时,引擎会先在自身属性上查找,没有就查找原型,一级级向上查找,如果到`Object.prototype`还是没有,则返回`undefined`。
**一级级向上,对性能有影响,寻找的层级越多,性能影响越大**
 
**原型链:**

 
- 实例 F1 通过`__proto__` 访问对应构造函数的原型 -> `FOO.prototype`
 
- 函数原型再通过`__proto__` 访问Object的原型 -> `Object.prototype`
 
- Object的原型的`__proto__` 指向 `null`
 
- 构造函数 `Foo.prototype` 通过`constructor`访问构造函数本身
 
- `Object.constructo` 指向 `Function`
 
- `Function.constructo` 指向 本身
 
- `Function.__proto__` 指向一个匿名函数
 
- 每个构造函数通过 `prototype` 访问原型
**只有函数才拥有`prototype`属性,基本上所有函数都有这个属性**
let fun = Function.prototype.bind()
当声明一个函数时自动创建 `prototype` 属性,
这个属性的值是一个对象(也就是原型),且只有一个属性 `constructor`
 

`constructor`

`prototype` 有一个属性 `constructor`,默认指向原型所在的构造函数
function Fn (){}
var f = new Fn ();
f.constructor == Fn //true
f.constructor == Function //false //可以从实例对象新建另一个实例
var b =new f.constructor();
b.constructor == Fn //true
`constructor `是一个公有且不可枚举的属性。一旦我们改变了函数的 prototype ,那么新对象就没有这个属性了,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。
function A(){}
console.log(A.prototype) // {constructor: ƒ}constructor: ƒ A()__proto__: Object
A.prototype="a"
console.log(A.prototype) //"a"

constructor作用:

- 让实例对象知道是什么函数构造了它,可以得知某个实例对象,是哪一个构造函数产生的。
- 如果想给某些类库中的构造函数增加一些自定义的方法,就可以通过 xx.constructor.method 来扩展

\_\_proto\_\_

基本上每个对象都有的隐式原型属性,指向创建该对象的构造函数的原型,实际指向`[[prototype]]`, 内部属性,我们并不能访问到,所以使用 _proto_ 来访问。
console.log({})
//__proto__: Objectconstructor: ƒ Object()hasOwnProperty: ....

当我们使用 new 操作符时,生成的实例对象拥有了 `__proto__`属性。

function Foo() {}
// 这个函数是 Function 的实例对象
// function 就是一个语法糖
// 内部调用了 new Function(...)
const a =1;
const fn = new Function("console.log(a)") // Function 的this始终指向 全局对象,除非手动改变this指向
fn()//
- 所有对象都可以通过原型链最终找到 Object.prototype ,虽然 Object.prototype 也是一个对象,但是这个对象却不是 Object 创造的,而是引擎自己创建了 `Object.prototype` 。
可以这样说,所有实例都是对象,但是对象不一定都是实例。
-首先引擎创建了 Object.prototype ,然后创建了 Function.prototype ,并且通过__proto__ 将两者联系了起来。
- Function.prototype 以后才有了 function Function() ,然后其他的构造函数都是 function Function() 生成的。
- 函数通过 `new Function()` 生成, 不是所有函数都是 `new Function() `产生的。 
 
总结:
> 1. Object 是所有对象的爸爸,所有对象都可以通过__proto__ 找到它
 
> 2. Function 是所有函数的爸爸,所有函数都可以通过__proto__ 找到它
 
> 3. Function.prototype 和 Object.prototype 是两个特殊的对象,他们由引擎来创建
 
> 4. 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
 
> 5. 函数的 prototype 是一个对象,也就是原型
 
对象的__proto__ 指向原型,__proto__将对象和原型连接起来组成了原型链

JavaScript 对象继承 OOP (三)

JavaScript 原型链 OOP(二)的更多相关文章

  1. JavaScript学习总结(十七)——Javascript原型链的原理

    一.JavaScript原型链 ECMAScript中描述了原型链的概念,并将原型链作为实现继承的主要方法.其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法.在JavaScript中, ...

  2. JavaScript原型链及其污染

    JavaScript原型链及其污染 一.什么是原型链? 1.JavaScript中,我们如果要define一个类,需要以define"构造函数"的方式来define: functi ...

  3. javascript原型链中 this 的指向

    为了弄清楚Javascript原型链中的this指向问题,我写了个代码来测试: var d = { d: 40 }; var a = { x: 10, calculate: function (z) ...

  4. 明白JavaScript原型链和JavaScrip继承

    原型链是JavaScript的基础性内容之一.其本质是JavaScript内部的设计逻辑. 首先看一组代码: <script type="text/javascript"&g ...

  5. Javascript 原型链资料收集

    Javascript 原型链资料收集 先收集,后理解. 理解JavaScript的原型链和继承 https://blog.oyanglul.us/javascript/understand-proto ...

  6. 资料--JavaScript原型链

    JavaScript原型链 原文出处:https://www.cnblogs.com/chengzp/p/prototype.html 目录 创建对象有几种方法 原型.构造函数.实例.原型链 inst ...

  7. JavaScript原型链:prototype与__proto__

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

  8. JS面向对象组件(二)--Javascript原型链

    原型链 : 实例对象与原型之间的连接,叫做原型链 –__proto__( 隐式连接 ),这就是原型链,平时我们是看不到的. 原型链的最外层 : Object.prototype function Aa ...

  9. 图解Javascript原型链

    本文尝试阐述Js中原型(prototype).原型链(prototype chain)等概念及其作用机制.上一篇文章(图解Javascript上下文与作用域)介绍了Js中变量作用域的相关概念,实际上关 ...

随机推荐

  1. HTTP,HTTPS端口号

    博主暂做个笔记,查询资料再纠正~~~~小白不要不假思索的抄走~~~ 一般情况下,HTTP默认工作端口是8000,HTTPS默认工作端口是443

  2. LCA【洛谷P2971】 [USACO10HOL]牛的政治Cow Politics

    P2971 [USACO10HOL]牛的政治Cow Politics 农夫约翰的奶牛住在N (2 <= N <= 200,000)片不同的草地上,标号为1到N.恰好有N-1条单位长度的双向 ...

  3. 模板【洛谷P3811】 【模板】乘法逆元

    P3811 [模板]乘法逆元 给定n,p求1~n中所有整数在模p意义下的乘法逆元. T两个点的费马小定理求法: code: #include <iostream> #include < ...

  4. ArrayList深度分析:ArrayList和数组间的相互转换

    一.ArrayList转换为数组ArrayList提供public <T> T[] toArray(T[] a)方法返回一个按照正确的顺序包含此列表中所有元素的数组,返回数组的运行时类型就 ...

  5. 数据结构8: 双向链表(双向循环链表)的建立及C语言实现

    之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链 ...

  6. vuex 浅认知

    什么是Vuex? Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式. 采用了集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 什么情况下我应该使用 ...

  7. Django易混淆问题

    1.Django本身提供了runserver 为什么不能用来 部署 runserver 方法是调试 Django 时经常用到的运行方式,它使用 Django 自带的  WSGI Server 运行,主 ...

  8. js apply和call

    apply()和call()这两个方法的作用是一样的,都是在特定作用域中调用函数,等于设置函数体内this对象的只,以扩充函数赖以运行的作用域 apply:方法能劫持另外一个对象的方法,继承另外一个对 ...

  9. C# 利用ITextSharp导出PDF文件

    最近项目中需要导出PDF文件,最后上网搜索了一下,发现ITextSharp比较好用,所以做了一个例子: public string ExportPDF() { //ITextSharp Usage / ...

  10. Robot Framework搭建

    需要安装的内容如下: 1. Python2.7.13(听说python3对RF支持的不是很好,所以我下的Python2) 2. wxPython 2.8.12.1(只能这个版本) 3. robotfr ...