Javascript原型总结

Javascript原型

本文为了解决以下问题:

  • Javascript中的对象
  • 原型中所涉及的概念(__proto__,prototype,constructor
  • 构造函数原型链
  • 完整对象59
  • 原型链
  • 数组原型链
  • 总结

Javascript中的对象

对象是若干属性的集合,在Javascript中,万物皆对象,方法(Function)是对象,方法的原型(Function.prototype)是对象

原型中所涉及的概念

原型:原型是一个对象,其他对象可以通过它实现继承。它为构造函数设置一个prototype属性。prototype属性包含一个对象,所有实例对象需要共享的属性和方法,都放在这个对象里面;那些不需要共享的属性和方法,就放在构造函数里面

原型对象(prototype):这个对象包含所有实例共享的属性和方法。

proto属性:所有对象都有属性proto,指向该对象的构造函数的原型对象。

1
2
3
4
5
6
7
8
 function Person(name){
 this.name = name;
 this.words = 'Winter is coming. ';
}
var a = new Person();
// a 是一个Person对象 默认拥有__proto__ 属性
console.log(a.__proto__ === Person.prototype); // true
白话就是 由谁创建 其__proto__ 就指向谁的 prototype

Function:方法(Function)是个特殊的对象,除了和其他对象一样有proto属性之外,还有自己特有的属性——原型属性(prototype)

prototype属性:这个属性是一个指针,指向一个对象(我们叫做原型对象),这个对象的用途就是包含所有实例共享的属性和方法。

1
2
3
4
5
function Animal (color) {
this.color = color
}
var dog = new Animal ('黑色')
console.log(dog.__proto__ === Animal.prototype); // true

constructor属性:原型对象有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数(它本身)

1
2
3
console.log(Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object); // true
console.log(Array.prototype.constructor === Array); // true

Tips

关于proto__

1 . 任何对象都拥有 __proto__(隐式原型) 属性, 一般指向他们的构造函数的原型 (prototype) .

1
2
var a = new Array () 
console.log(a.__proto__ === Array.prototype); // true

2、所有方法(Function)的__proto__都指向Function.prototype

1
2
3
4
5
6
7
8
function XXXXX (color) {
this.color = color
}
var dog = new Animal ('黑色')
console.log(XXXXX.__proto__ === Function.prototype); // true
console.log(Array.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype ); // true
console.log(Function.__proto__ === Function.prototype); // true

3 . 原型链的顶端是Object.prototype,其 __proto__为 null

1
2
console.log(Object.prototype.__proto__ === null); // true
// 这是一个特例,为了避免JavaScript死循环.

4 . 所有函数都拥有prototype (显式原型)属性,除Object.prototype.proto === null外,其他任何函数的 prototype.proto 都指向 Object.prototype

1
2
3
4
5
console.log(XXXXX.prototype.__proto__ === Object.prototype);  // true
console.log(Array.prototype.__proto__ === Object.prototype); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true
//特例
console.log(Object.prototype.__proto__ === null ); // true

关于prototype

只有方法(Function)才有prototype属性

关于constructor

只有原型对象才constructor属性,指回原构造函数

1
console.log(Array.prototype.constructor === Array);       // true

构造函数原型图

1
2
3
4
function Animal (color) {
this.color = color
}
var dog = new Animal ('黑色')

当我们创建一个函数时原型如下:

backgroud

1
2
//补充
Animal.prototype._proto_ === Object.prototype

完整对象原型链

1
var obj = { name: '陈二狗' }

backgroud

数组原型链

1
var arr = ['第一个数','第二个数','第三个数']

backgroud

总结

现在就对上面的例子中分析得到的结果/关系进行图解,相信这张图可以让你豁然开朗。

backgroud

对于上图的总结如下看具体代码:

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
function test () { 
// some code
}
var obj = {} // 可以看做是 var obj = new Object ()
var arr = [] // var obj = new Array ()
// 因此他们的构造函数分别是 Object 和 Array
console.log(test.__proto__ === Function.prototype); // true
console.log(obj.__proto__ === Object.prototype); // true
console.log(arr.__proto__ === Array.prototype); // true

Object Function Array 本身也都是一个函数,由于是最常用的,所以JavaScript帮我们实现了
console.log(Function.__proto__ === Function.prototype); // true
console.log(Object.__proto__ === Function.prototype ); // true
console.log(Array.__proto__ === Function.prototype); // true
console.log(test.__proto__ === Function.prototype); // true

console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null ); // true
console.log(Array.prototype.__proto__ === Object.prototype); // true
console.log(test.prototype.__proto__ === Object.prototype); // true

console.log(Function.prototype.constructor === Function); // true
console.log(Object.prototype.constructor === Object ); // true
console.log(Array.prototype.constructor === Array); // true
console.log(test.prototype.constructor === test); // true

console.log(Function.prototype. === Function.prototype); // true

完结