构造函数、原型和原型链

var n=1; 与 var n=new Numer(1)的区别
全局函数(构造函数)
原型(prototype)和原型链
对象.proto === 构造了它的全局函数.prototype (新创建的对象由对应的全局函数构造得来)
全局函数.proto === Function.prototype(全局函数都是由Function构造出来的)
全局函数.prototype.proto === Object.prototype (全局函数的共有属性从Object的共有属性中引用)
Object.prototype.proto === null (Object的共有属性引用至null)
原型 === 共有属性 === prototype
原型链:顺着proto组成的链子一直往下走,直到proto 为 null

全局函数(构造函数)

全局函数都是由Function构造的,因此
全局函数.proto === Function.prototype
Function.proto === Function.prototype
1.Number

1
2
var n = new Number(1) 创建一个 Number 对象
var n = 1var n = new Number(1) 的区别是什么?看内存图

2.String

1
2
var s = new String('hello') 创建一个 String 对象
'hello'new String('hello') 的区别是什么?看内存图

3.Boolean

1
2
3
4
5
6
7
8
var b = new Boolean(true) 创建一个 Boolean 对象
truenew Boolean(true) 的区别是什么?看内存图
var a = false;
var b = new Boolean(false);
if(a){console.log(1)}
if(b){console.log(2)}
结果是2,因为b是个对象

4.Object

1
2
3
4
var o1 = {}
var o2 = new Object()
o1 和 o2 的数据没区别
但是o1不等于o2,因为他们两个在Stack区的地址不同

原型和原型链

原型 === 共有属性 === prototype
原型链:顺着proto组成的链子一直往下走,直到proto 为 null

1
2
3
4
5
6
7
8
9
10
11
12
13
创建一个对象后的原型链
var arr = [1,2,3];
arr.__proto__ === Array.prototype //新创建的对象由对应的全局函数构造
arr.__proto__.__proto__ === Object.prototype
arr.__proto__.__proto__.__proto__ === null
所以它的原型链是:arr --> Array.prototype --> Object.prototype --> null
全局函数的原型链
Array.__proto__ === Function.prototype //全局函数由Function构造
Array.__proto__.__proto__ === Object.prototype
Array.__proto__.__proto__.__proto__ === null
所以它的原型链是:Array.prototype --> Function.prototype --> Object.prototype --> null

隐藏的公用属性(prototype)

所有对象都有 toString 和 valueOf 属性,那么我们是否有必要给每个对象一个 toString 和 valueOf 呢?

明显不需要。

JS 的做法是把 toString 和 valueOf 放在一个对象里(Object.prototype)

然后让每一个对象有1个隐藏的 proto 存储这个「公用属性组成的对象」的地址。

Object的proto指向Function.prototype

1
2
3
4
5
var obj ={
name: 'stage',
age: 24
};
console.log(obj);//{name: "stage", age: 24} 以及隐藏的__proto__指向Function.prototype


重点公式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var 对象 = new 全局函数() //全局函数包括Number(123)、String('123')/Function()等
对象.__proto__ === (构造了它的)全局函数.prototype
//.__proto__用来存原型(prototype)的地址,从而引用prototype的数据
//__proto__是对象的属性
//prototype是函数的属性
//对象的__proto__指向函数的prototype
比如:
var num = new Number(1);
num.__proto__ === Number.prototype;
//num由Number构造生成
//创建的num,它的隐藏的__proto__指向【Number】的公用属性Number.prototype
num.__proto__.__proto__ === Object.prototype;
//创建的num,它隐藏的__proto__指向Number.prototype,
Number.prototype.的隐藏__proto__继续指向Object的公用属性Object.prototype
----------
obj.toString === Object.prototype.toString
//对象的toString方法,实际上是调用了Object的公用属性(prototype)的toString方法
-----------
var fn = new Function()
fn.__proto__ === Function.prototype //fn由Function构造生成
由于Function的是由Function构造的,所以
Function.__proto__ === Function.prototype
也就是说,Function.__proto__指向它本身的prototype
-------------
Object的_proto_指向Function.prototype
Object.__ptoto__ === Function.prototype,因为 FunctionObject 的构造函数。

-------------本文结束感谢您的阅读-------------