目录

prototype

__proto__

原型链

构造函数创建对象实例


今天同事小英童鞋问了我一个问题:

function Foo(firstName, lastName){this.firstName = firstName;this.lastName = lastName;
}
Foo.prototype.logName = function(){Foo.combineName();console.log(this.fullName);
}
Foo.prototype.combineName = function(){this.fullName = `${this.firstName} ${this.lastName}`
}var foo = new Foo('Sanfeng', 'Zhang');
foo.logName(); // Uncaught TypeError: Foo.combineName is not a function

小英童鞋认为Foo的原型对象是Foo.prototype,所以Foo会继承Foo.prototype的属性,调用Foo.combineName()相当于调用Foo.prototype.combineName(),但结果Foo.combineName()不是一个方法。

会造成这个问题的原因一定是因为小英童鞋弄混了原型和继承的一些原理,下面我们来整理一下原型和继承的相关原理,找出问题的根本原因。

prototype

prototype是一个拥有 [[Construct]] 内部方法的对象才有的属性。

例如函数,对象的方法,ES6 中的类。注意 ES6 中的箭头函数没有 [[Construct]] 方法,因此没有prototype这个属性,除非你为它添加一个。

当创建函数时,JavaScript 会为这个函数自动添加prototype属性,这个属性指向的是一个原型对象Functionname.prototype。我们可以向这个原型对象添加属性或对象,甚至可以指向一个现有的对象。

__proto__

接下来我们说说继承,每个对象都有一个__proto__属性,这个属性是用来标识自己所继承的原型。

注意: JavaScript 中任意对象都有一个内置属性 [[Prototype]] ,在ES5之前没有标准的方法访问这个内置属性,但是大多数浏览器都支持通过__proto__来访问。以下统一使用__proto__来访问 [[Prototype]],在实际开发中是不能这样访问的。

原型链

JavaScript 可以通过prototype__proto__在两个对象之间创建一个关联,使得一个对象就可以通过委托访问另一个对象的属性和函数。

这样的一个关联就是原型链,一个由对象组成的有限对象链,用于实现继承和共享属性。

构造函数创建对象实例

JavaScript 函数有两个不同的内部方法:[[Call]] 和 [[Construct]] 。

如果不通过new关键字调用函数,则执行 [[Call]] 函数,从而直接执行代码中的函数体。

当通过new关键字调用函数时,执行的是 [[Construct]] 函数,它负责创建一个实例对象,把实例对象的__proto__属性指向构造函数的prototype来实现继承构造函数prototype的所有属性和方法,将this绑定到实例上,然后再执行函数体。

模拟一个构造函数:

function createObject(proto) {if (!(proto === null || typeof proto === "object" || typeof proto === "function"){throw TypeError('Argument must be an object, or null');}var obj = new Object();obj.__proto__ = proto;return obj;
}var foo = createObject(Foo.prototype);

至此我们了解了prototype__proto__的作用,也了解使用构造函数创建对象实例时这两个属性的指向,以下使用一张图来总结一下如何通过prototype__proto__实现原型链。

从上图我们可以找出foo对象和Foo函数的原型链:

foo.__proto__ == Foo.prototype;
foo.__proto__.__proto__ == Foo.prototype.__proto__ == Object.prototype;
foo.__proto__.__proto__.__proto__ == Foo.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null;

Foo.__proto__ == Function.prototype;
Foo.__proto__.__proto__ == Function.prototype.__proto__;
Foo.__proto__.__proto__.__proto__ == Function.prototype.__proto__.__proto__ == Object.prototype.__proto__ == null;

构造函数Foo的原型链上没有Foo.prototype,因此无法继承Foo.prototype上的属性和方法。而实例foo的原型链上有Foo.prototype,因此foo可以继承Foo.prototype上的属性和方法。

到这里,我们可以很简单的解答小英童鞋的问题了,在Foo的原型链上没有Foo.prototype,无法继承Foo.prototype上的combineName方法,因此会抛出Foo.combineName is not a function的异常。要想使用combineName方法,可以这样Foo.prototype.combineName.call(this),或者这样this.combineName()this指向实例对象)。

javascript es6 属性 __proto__ prototype 原型链 简介相关推荐

  1. 进击的 JavaScript 之(七) 原型链

    原文链接:周大侠啊 进击的 JavaScript (七) 之 原型链 算是记录一下自己的学习心得吧,哈哈 首先说一下,函数创建的相关知识 在JavaScript中,我们创建一个函数A(就是声明一个函数 ...

  2. JavaScript系列—一道十面埋伏的原型链面试题

    这道题是我面试的时候碰到的 function Parent() {this.a = 1;this.b = [1, 2, this.a];this.c = { demo: 5 };this.show = ...

  3. JS中prototype、__proto__以及原型链

    1.对象的三角恋关系 1.每个"构造函数"中都有一个默认的属性, 叫做prototype prototype属性保存着一个对象, 这个 对象 称之为"原型对象" ...

  4. javascript对象、类与原型链

    js是一个基于对象的语言,所以本文研究一下js对象和类实现的过程和原理. 对象的属性及属性特性 下面是一个对象的各个部分: var person = {name: "Lily",a ...

  5. JavaScript的面向对象原理之原型链

    二.JavaScript的对象 为了能够清楚的解释这一切,我先从对象讲起.从其他面向对象语言(如Java)而来的人可能认为在JS里的对象也是由类来实例化出来的,并且是由属性和方法组成的. 实际上在JS ...

  6. 学习es6的继承与原型链

    es6出现了class类但是此类非彼类和java不一样 上代码 这是typescript未编译的样子 class Pepole{age:number=nullname:string="&qu ...

  7. ES6 继承(复习原型链继承)

    2019独角兽企业重金招聘Python工程师标准>>> 原型链继承 <script type="text/javascript">/* 原型链 继承 ...

  8. JavaScript 变量、函数与原型链

    定义 || 赋值 1-函数的定义 函数定义的两种方式: "定义式"函数:function fn(){ alert("哟,哟!"); } "赋值式&qu ...

  9. JavaScript简餐——继承之原型链继承

    文章目录 前言 一.实现方式 二.继承实例 三.问题所在 1.引用值误修改 2.子类型实例化时无法给父类构造函数传参 四.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在 ...

最新文章

  1. sar分辨率公式_初识合成孔径雷达SAR
  2. python中正确的输入语句x、y=input_语句x=input()执行时,如果从键盘输入12并按回车键,则x的值是( )。_学小易找答案...
  3. 河北省往届高考成绩查询2021,2021河北高考成绩查询时间 高考成绩查询入口
  4. go waitgroup.done()异常处理_Go 异常处理
  5. javascript基础学习
  6. synchronized方法与synchronized代码块的区别
  7. APP测试之Monkey压力测试(二)
  8. java web应用程序_说说Java Web中的Web应用程序|乐字节
  9. matlab2c使用c++实现matlab函数系列教程-diag函数
  10. JavaWeb知识点:Http协议
  11. 常见数据类型的手机二维码生成与识别格式参考
  12. 记录一下filter
  13. KinhDown(百度网盘第三方下载工具稳定版)
  14. android dff播放器,无损音乐解码播放器
  15. DFT泄漏 频谱泄漏 (FFT)
  16. 计算机论文的研究思路与方法,计算机毕业论文开题报告教学网站的设计与实现...
  17. MOGRE学习笔记(2) - MOGRE基础知识总结
  18. 联璧品牌发布会在重庆隆重举行 联璧CEO侬锦做重要讲话
  19. win7连接sftp_Windows下用sftp巧妙打造安全传输
  20. 谷粒商城基础篇——Day01

热门文章

  1. java 鼠标 停止工作原理,java系统级的键盘和鼠标状态
  2. Linux Kernel TCP/IP Stack — L3 Layer — netfilter 框架 — conntrack(CT,连接跟踪)
  3. 用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板
  4. PowerShell批量设置PATH环境变量
  5. Redis与DB数据同步问题
  6. 一条数据的HBase之旅,简明HBase入门教程-Write全流程
  7. Dynatrace DPM数字性能管理方案确保安吉星领跑车联网技术
  8. 深入Android内存泄露
  9. Windows打印体系结构之打印驱动框架
  10. System.Windows.Forms.ListView : Control