公用属性
我们知道,所有对象都有 toString 和 valueOf 属性,但如果给每一个对象都分配一个 toString 和 valueOf ,会十分地占内存,如图
每一个对象都分配 toString 和 valueOf显然这么做很蠢。
因此,JS 的做法是把 toString 和 valueOf 放在一个对象里(暂且叫做公用属性组成的对象),然后让每一个对象的 _ _ proto _ _ 存储这个「公用属性组成的对象」的地址。
举个栗子
执行 o1.toString() 时,首先进入对象 o1 查找是否存在 .toString 属性,如果没有,再通过 _ _ proto _ _ 进入所有对象的公用属性中找到 toString 函数
同时,这时候如果再声明一个对象 o2 ,我们会发现虽然 o1 与 o2 不相等,但却有 o1.toString === o2.toString
,这也说明了对象确实是存在公用属性的
另外,除 Object 对象之外,Number、String、Boolean 对象都分别有自己独有的公用属性,以 Number 对象为例:
树形结构图每个实例对象( object )都有一个私有属性(称之为 _ _ proto _ _ )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( _ _ proto _ _ ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。
上图中红色的连线就被称之为原型链
代码即便不写代码,浏览器也是会有 prototype 的,且浏览器的 prototype 无法被修改
image.png注意:Object.prototype对象也有_ _ proto _ _属性,但它比较特殊,为null
重要公式
通用公式
var 对象 = new 函数()
对象.__proto__ === 对象的构造函数.prototype
注意:
一、构造函数的概念:
任何函数都可以当成构造函数
function CreateFunc(){ }
只要把一个函数通过new的方式来进行调用,我们就把这一次函数的调用方式称之为:构造函数的调用
new CreateFunc(); 此时CreateFunc就是一个构造函数
CreateFunc(); 此时的CreateFunc并不是构造函数
也可以说,构造函数就是返回一个新的对象的函数
二、七种基本数据类型中只有 number、string、boolean、object(array、function)分别有相应的构造函数 Number()、String()、Boolean()、Object()、Array()、Function(),undefined和null是没有构造函数的。
推论
var number = new Number()
number.__proto__ = Number.prototype
注意大小写,number 和 Number 是不同的
//
var object = new Object()
object.__proto__ = Object.prototype
//
var function = new Function()
function.__proto__ = Function.prototype
另外,所有函数都是由 Function 构造出来的,所以
Number.__proto__ = Function.prototype // 因为 Number 是函数,是 Function 的实例
Object.__proto__ = Function.prototype // 因为 Object 是函数,是 Function 的实例
Function.__proto__ == Function.prototye // 因为 Function 是函数,是 Function 的实例!
网友评论