Appearance
原型(prototype)、原型链(__proto__
)
函数
普通函数、类(所有的类:内置类、自己创建的类)
对象
- 普通对象、数组、正则、Math、arguments...
- 实例是对象类型的(除了基本类型的字面量创建的值)
- prototype 的值也是对象类型的
- 函数也是对象类型的
原型(prototype)
所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(
null
除外)所有的函数数据类型都天生自带一个属性:prototype(原型),这个属性的值是一个对象,浏览器会默认给它开辟一个堆内存
在浏览器给 prototype 开辟的堆内存中有一个天生自带的属性:constructor, 这个属性存储的值是当前函数本身
所有的引用类型都有一个
__proto__
的属性,这个属性指向当前实例所属类的 prototype (如果不能确定它是谁的实例,都是 object 的实例)每一个类都把供实例调取的公共属性方法存储到自己的原型上(原型 prototype 的作用就是存储一些公共的属性和方法,供它的实例调取和使用)。
JS 在创建对象的时候,都有一个
__proto__
的内置属性,用于指向创建它的构造函数的原型对象。
js
// 要点一:自由扩展属性
var obj = {}; obj.a = 100;
var arr = []; arr.a = 100;
function fn () {}
fn.a = 100;
// 要点二:__proto__
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
// 要点三:函数有 prototype
console.log(fn.prototype)
// 要点四:引用类型的 __proto__ 属性值指向它的构造函数的 prototype 属性值
console.log(obj.__proto__ === Object.prototype)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
原型链

- 它是一种基于
__proto__
向上查找的机制。当我们操作实例的某个属性或者方法的时候,首先找自己空间中私有的属性或者方法 - 找到了,则结束查找,使用自己私有的即可
- 没有找到,则基于** proto** 找所属类 prototype , 如果找到就用这个公有的,如果没找到,基于原型上的、_
__proto__
继续向上查找,一直找到 0bject.prototype 的原型为止,如果在没有,操作的属性或者方法不存在 - 每个对象都有
__proto__
属性,但只有函数对象才有 prototype 属性
javascript
// 原型 prototype 原型链 __proto__
// 每一个函数都有prototype属性
// 每一个对象都有__proto__属性
function Aniam() {
var n = 100;
this.a = "值";
this.type = "哺乳类";
this.AA = function () {
console.log(`AA[私]`);
};
this.BB = function () {
console.log(`BB[私]`);
};
}
Fn.prototype.AA = function () {
console.log(`AA[公]`);
};
var f1 = new Fn();
var f2 = new Fn();
console.log(f1.n);
Aniam.prototype.type = "哺乳";
Aniam.prototype.b = "原型";
// 先会查找自身的属性、向上查找则查找父类
console.log(Aniam.prototype);
let animal = new Aniam();
// delete animal.type
console.log(animal.type);
console.log(animal.__proto__ === Aniam.prototype);
console.log(animal.__proto__.__proto__ === Object.prototype);
console.log(Aniam.prototype.constructor === Aniam);
console.log(Object.__proto__.__proto__);
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
34
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
34
特殊 Function Object
javascript
// 特殊Function Object(可以充当对象、也可以充当函数)
console.log((Function.__proto__ = Function.prototype));
console.log("====================================");
// in 关键字 会判断这个属性是否属于原型 或者实例上的属性
// hasOwnProperty 智慧看是否存在当前实例上
console.log(animal.hasOwnProperty("a"));
console.log("b" in animal);
console.log("====================================");
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
那么如何判断这个属性是不是对象本身的属性呢?使用hasOwnProperty
,常用的地方是遍历一个对象的时候。
js
var item
for (item in f) {
// 高级浏览器已经在 for in 中屏蔽了来自原型的属性,但是这里建议大家还是加上这个判断,保证程序的健壮性
if (f.hasOwnProperty(item)) {
console.log(item)
}
}
1
2
3
4
5
6
7
2
3
4
5
6
7
原型链中的this
所有从原型或更高级原型中得到、执行的方法,其中的this
在执行时,就指向了当前这个触发事件执行的对象。因此printName
和alertName
中的this
都是f
。