引言
- 原型和原型链是js中比较重要但也是比较难的内容;
- 正是因为有了原型链的概念,js中的继承才成为可能;
- 本文结合js内置的数据类型,说说我对js原型和原型链的理解;
Javascript和Java语言设计思想的区别
- java
- java是完全OOP的语言,对Java的认知是从类与对象开始的;
- class是一类具有共同特点的物体的抽象,object(对象)是某个class下具体的一个实现,Object类是所有类的顶层父类;
- js
- javascript是基于原型(而不是基于类的,尽管ES6新增了class关键字)的面向对象的语言,没有类的概念(ES6新增的类是语法糖);
- javascript中的class本质上是一个函数对象,和java中的类的概念有本质区别;
- javascript存在类似面相对象的特性,这就是原型和原型链,从而派生出了类似于父类子类和继承的概念;
- 本图来自这里
对象和数据类型
- js中的数据类型:
- 数据类型:string、number、boolean、object(数组、对象、null)、undefined、function;
- 数组、对象、null是不精确的数据类型,在用typeof判断时均返回object;
- typeof关键字只能返回非精确的数据类型;
- 用Object.prototype.toString判断精确的数据类型;
- 首字母大小写的区别:
- 小写(string、number、boolean、object、null、undefined、function)表示数据类型;
- 大写(String、Number、Boolean、Object、Array)表示js的内置对象(全部是function类型);
- js中对象的含义:
- 广义的对象(js一切皆为对象、包括window和document对象、也包括String、Number、Boolean、Object、Array、Math、Date等内置对象);
- 狭义的数据类型(数组、对象、null类型均为object,即被typeof关键字判断为object类型);
- “对象”这种数据类型(请参考我的另一篇博客);
原型链概述
- JavaScript中的每个对象都有一个内部的链接指向另一个对象,这个对象就是原对象的原型,这个原型对象也有自己的原型,直到对象的原型为 null 为止(也就是没有原型);
- 这种一级一级的链结构就称为原型链(prototype chain);
- 每个对象都有一个隐形的属性proto(两边都是双下划线),这个属性的值为一个地址,指向这个属性的原型对象,原型对象是每个对象都有指向的隐形对象;
- new出来的普通对象没有构造器,就没有prototype属性;
- proto属性也可用someObject.[[Prototype]] 表示;
- 如果一个对象是object类型,它的proto属性总是指向Object.prototype;
- 如果一个对象是function类型,它的proto属性总是指向Function.prototype;
- 继承属性:JavaScritp引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined;
各种对象原型链的图示
- String对象的原型链
1 | var s = "sss"; |
- Number对象的原型链
1 | var n = 1; |
- Boolean对象的原型链
1 | var b = true; |
- Array对象的原型链
1 | var a =[1,2,3]; |
- Function对象的原型链
1 | var f = function(){}; |
- Object对象的原型链
1 | var o = {}; |
- 自定义对象的原型链
1 | function Person(name,age){ |
- 最后附上一张知乎上面大神画的图,清楚地表示了Object和Function的继承关系