原型:原型是一个对象,其他对象可以通过它实现属性继承;原型分两类:显式原型(prototype)和隐式原型(__proto__)(proto左右两边都是两条下划线),prototype是函数才有的属性,_proto_是每个对象都有的属性。
原型的规则:
1、所有函数都有prototype属性,属性值是一个普通对象。
console.log(fn.__proto__);
2、所有的引用类型(数组、对象和函数),都具有自由扩展属性(也就是原型属性啦)。(null除外)
<script>
var obj ={};
obj.a = 100;
var arr =[];
arr.a = 100;
function fn()
{
}
fn.a =100;
</script>
3、所有的引用类型都具有__proto__属性,并且指向他们的构造函数的prototype属性。
console.log(obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
4、如果一个对象找不到本身的属性,那么会寻找构造这个对象的属性。
注意:大多数情况下,_proto_可以理解为“构造器的原型”,即:_proto_ === constructor.prototype
栗子:
var Obj ={};Obj.a = 1;
var arr = []; arr.a =2;
function fn() {}
fn.a = 3;
console.log(Obj.__proto__);
console.log(arr.__proto__);
console.log(fn.__proto__);
console.log(Obj.__proto__ === Object.prototype);
console.log(arr.__proto__ === Array.prototype);
console.log(fn.prototype);
console.log(Obj.prototype);
输出:
//证明所有的引用类型都有_proto_属性,指向构造它的函数prototype属性
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
[constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]
ƒ () { [native code] }
true
true
//证明只有函数有prototype属性,普通对象没有显示原型属性
{constructor: ƒ}
undefined