越努力,越幸运,做个ccode~

0%

原型与原型链

普通类型与对象的区别

在javascript中,一切东西都可以被当做对象

var n1 = 1
var n2 = new Number(1)
n1.toString() // "1"
n2.toString() // "1"

这两种方法都是定义一个数字1,但n1是基本类型,n2是对象
但为什么n1也有toString()方法呢,因为在调用n1.toString()时,内存中会临时生成一个对象temp=new Number,temp.toString() 的结果给n1.toString()
同理,字符串也有两种声明的方法

var s1 = '123'
var s2 = new String('123')
s1.toString() // '123'
s2.toString() // '123'

共有属性(原型对象)

var n1 = new Number(1)
var n2 = new Number(2)
var s1 = new String('123')
var s2 = new String('abc')
n1.valueOf()  // 1
n2.valueOf()  // 2
s1.charAt(0)  // "1"
s2.charAt(0)  // "a"
s1.valueOf()  // "123"
s2.valueOf()  // "abc"

为什么s1和s2都有charAt()属性,n1和n2都有valueOf()属性,n1,n2,s1,s2都有valueOf()属性?

javascript为了节省空间,将n1和n2的公用属性封装在了Number.prototype,Number的原型对象中,在n1调用属性时,会先在自身的属性上找,如果没有则继续向__proto__属性中找,找到的话就调用该属性,如果没找到则继续向下一级__proto__中找,找到Object.prototype都还没找到,就返回undefined。而Number的原型对象有valueOf()属性,所以n1和n2都可以调用此方法。

javascript将所有对象共有的属性封装在了Object的原型对象中(Object.prototype),但是因为Number,String,Boolean类型又有不同的属性,所以分别又有Number.prototyeBoolean.prototype,String.prototype分别存储了Number,String,Boolean类型的共有属性,不同类型的实例对象可以通过__proto__访问该类型的原型对象,Number,String,Boolean的实例对象的__proto__又指向Object.prototype.

prototype 与 proto

拿Number举例,var n = new Number,n是对象,n有proto属性,指向Number的原型对象(Number共有属性)==> Number.prototype
而原型对象也有proto属性,Number原型对象的proto指向Object的原型对象==>Object.prototype

var number = new Number(1)
number.__proto__ === Number.prototype  // true
Number.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null
Number.__proto__ === Function.prototype // true

number的原型链
number ==> Number.prototype ==> Object.prototype ==> null

var string = new String('123')
string.__proto__ === Number.prototype // true
String.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null
String.__proto__ === Function.prototype // true

string的原型链
string ==> String.prototype ==> Object.prototype ==> null

var bool = new Boolean(true)
bool.__proto__ === Boolean.prototype // true
Boolean.prototype.__proto__ === Object.prototype // true
Object.prototype.__proto__ === null
Boolean.__proto__ === Function.prototype // true

bool的原型链
bool ==> Boolean.prototype ==> Object.prototype ==> null

以上总结 一个公式

var 对象 = new 函数()
对象.__proto__ === 函数.prototype
函数.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
函数.__proto__ === Function.prototype

对象类型的原型链最短,直接指向Object.prototype

var obj = new Object()
obj.__proto__ === Object.prototype  // true
Object.prototype.__proto__ === null  // true
Object.__proto__ === Function.prototype  // true

obj的原型链
obj ==> Object.prototype ==> null

Function函数比较特殊

Function._proto__ === Function.prototype
Function.prototype.__proto__ === Object.prototype