原型链初步学习
原型链初步学习
- 这篇博客只是我初步理解原型链的一个个人学习笔记,写的比较粗略,且有的地方可能理解错误.
- 更多更专业的关于原型链的解释请看JavaScript深入之从原型到原型链和阮一峰的博客:Javascript继承机制的设计思想
JS标准库里几个构造函数之间的关系

每个对象都有
toString()
和valueOf()
函数,如果每个对象里都存这样的相同的函数,那会浪费内存.问题解决方法:原型链
把toString()
和valueOf()
等函数单独存放在一个对象里,原来对象里的toString()
和valueOf()
只存地址,指向这个地址

当声明对象是,出来自己定义的属性,还有一个隐藏的属性
__proto__
里面存的是toString()
和valueOf()
等的地址
他的值就是公用属性的值


共有的属性和方法
在执行o1.toString()
是发生的事:
首先看o1
是不是真正的对象,如果不是,就包装成临时对象,用完再回收垃圾,然后进入对象,看他有没有toString
方法,如果有特有的toString()
,就用,如果没有,就进入__proto__
属性去找toString()
方法.

说明所有的
toString()
都是同一个地址
__proto__
进阶

代码:

第一层的toString()
是Number()
特有的,可以转换成16进制
toString(16)
,第二层里面的的toString()
是所有对象都有的公共属性.比如找valueOf()
如果在第一层里 __proto__
找不到,就去第二层找.



原型链
所有的共有属性,,如果没有东西引用他,就会被垃圾回收,那么谁在引用他呢?
答案是 prototype ,prototype
的意思是 原型.
所有函数都有protoype
属性,包括构造函数.即String()
,Number()
,Boolean()
,Object()
有protoype
在最开始JS初始化的时候,函数的protoype
属性会加载到内存当中
原型===共有属性
Object.prototype
意思还是Object
的共有属性


Object
是构造函数(JS里函数也是一种对象,也可以有方法,可以 有属性)函数名字加
()
就是执行.

Number
的共有属性
共有属性的共有属性


其他String
,Boolean
的原型也是一样

new
做的事情,一创造一个哈希,二绑定原型(共有属性),即把__proto__
指向该有的共有属性,也就是原型
__proto__
与prototype
的关系
[__proto__
指向prototype
],
在无代码情况下
window
里面有Number
属性(函数也是对象,也可以有属性)
实际上为
Number:function Number(){}
这个


可以看到
prototype
是用来指向这些共有属性的,不然这些共有属性就被垃圾回收了,所以要用一个线来牵引着.如图


所以:
-
prototype
是浏览器开始就准备好了的,用来防止共有属性被垃圾回收的, -
__proto__
是在开始写代码的时候用来引用共有函数的. -
String.prototype
是String
的公用属性的引用,是JS在初始化的时候就已经存在的,用他是因为如果不用他,那么公用属性就跑了,被垃圾回收了 -
's'.__proto__
是String
的公用属性的引用,是在声明新对象的时候存在的,有他是因为我要用他,用公用属性
共同点就是都是公共属性的引用.
var o1 = {};
o1.__proto__ === Object.prototype//true
Number.prototype.__proto__===Object.prototype//true
var s1 = new String('s1');
s1.__proto__ === String.prototype//true

对象与构造函数

形式
总结的式子

只有函数才能
有prototype
两个属性对比:
共同点:存的地址相同,都指向同一个对象
不同点:一个是对象的属性,一个是函数的属性
面试题:
1
'1'.__proto__
'1'
会创建一个临时String对象,然后指向String.prototype
2
函数.prototype
是一个对象,那么
var obj = 函数.prototype;
obj.__proto__ === Object.prototype;//true
函数.prototype.__proto__ === Object.prototype;//true
成立(可以看上图无代码的时候)
Number.prototype.__proto__ === Object.prototype
//true
String.prototype.__proto__ === Object.prototype
//true
Boolean.prototype.__proto__ === Object.prototype
//true
成立