普通类型与对象的区别
在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.prototye
,Boolean.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