函数原型prototype以及对象的隐式原型__prot0__的基本了解
prototype原型:
一. 函数与对象的关系
1. 函数是对象的一种(函数是对象类型)
例: function fn1(){.........}
console.log(fn1 instanceof Object);
返回true,说明函数(fn1)是对象类型.
2. 对象是由函数创建的
例: var obj = new Object();
var arr = new Array(3);
arr[0] = 0;
arr[1] = 1;
arr[2] = 2;
console.log(typeof Object); //obj由Object创建
console.log(typeof Array); // arr由Array创建
返回: 上面两句console.log()语句都返回Function,
说明对象是由函数创建的.
二. prototype 原型(函数的属性)
1. 原理: prototype是函数里的属性,每一个函数都有prototype这个属性,这个属性 的值是一个对象,这个对象默认只有一个constructor的属性,且这个对象指向的是该函数本身.
2. 构造函数中的属性与原型中的属性的区别
1. 构造函数中的属性(或方法)
例: function fun(){
this.arr = [1,2,3,4,5];
}
var fun1 = new fun();
fun1.arr.push(6);
var fun2 = new fun();
console.log(fun1.arr); //返回{1,2,3,4,5,6}
console.log(fun2.arr); //返回{1,2,3,4,5}
说明:构造函数中的属性,对于由该函数所创建的对象来说,该属性是各自独立拥有的,即fun1里的arr,与fun2里的arr是两个不同的数组对象,占用的是不同的内存区域.
2. 原型中的属性(或方法)
例: function fun(){.....}
fun.prototype.arr = [1,2,3,4,5];
var fun1 = new fun();
fun1.arr.push(6);
var fun2 = new fun();
console.log(fun1.arr); //返回{1,2,3,4,5,6}
console.log(fun2.arr); //返回{1,2,3,4,5,6}
说明: 在函数的原型里设置的属性,对于由该函数所创建的对象来说,该属性是这些对象所共同享有的,这个属性在内存中始终都只占用一块区域;即修改任何一个对象的该属性的值,其他对象的该属性的值也会被修改,因为它们共享一块内存区域
总体说明: 1. 由上可见,把属性定义在原型中,比定义在构造函数内所耗的内存更小(始终都只占用一块内存区域).
2. 构造函数内的定义的属性的优先级高于原型中定义的属性的优先级;如果定义了同名称的属性或方法,构造函数内的属性或方法会覆盖原型中的同名称的属性或方法.
3. 所以,如果没有特殊情况,我们一般在函数体内定义属性,在原型中定义行为.
三. __proto__ 隐式原型(对象的属性)
1. 原理: __proto__是对象的属性,每一个对象都有__proto__这个属性,对象的这个属性指向的是创建该对象的函数的原型
例: function Person(){}
var p1 = new Person();
console.log(p1.__proto__); //返回Person{}这个函数
console.log(Person.prototype); //返回Person{}这个函数
解释: 1. (p1.__proto__)指向的是Person这个函数的原型(Person.prototype),(Person.prototype指向的是Person {},故(p1.__proto__)最终所返回的结果就是Person{}这个函数;
2. Person.prototype指向的就是Person{}这个函数
综上, 故(p1.__proto)===(Person.prototype)这个表达式返回为true.
2. 各种指向(fun1为一个函数)
1. fun1.prototype.__proto__ ----> Object.prototype
解释: 1. 函数的prototype是一个对象,故其有__proto__属性;
2.这里的prototype属于自定义函数,而自定义函数本质上都是通过 Object函数来创建的;
3. Object.prototype.__proto__ ----> null;
2. fun1.__proto__ ----> Function.prototype
解释: 1. 函数是对象类型,故其有__proto__这个属性;
2. 函数都是被Function创建,故fun1就是被Function创建的,所以创建
fun1这个函数对象的函数原型为Function.prototype;
引出: Object是函数,故Object被Function创建: Object.__proto__ ----> Function.prototype;
3. Function.__proto__ ----> Function.prototype
解释: 1. Function是函数,函数又是对象的一种,故Function也有__proto__属性;
函数都是被Function创建,故Function这个函数对象是被其自身所创建,故
创建Function这个函数对象的函数原型为Function.prototype;
4. Function.prototype.__proto__ ----> Object.prototype
解释: 1. Function的prototype是被Object所创建的对象,故这个prototype的__proto__指向的是 Object.prototype;
四. instanceof (判断对象的类型)
1. typeof 是用于判断值类型,String/Boolean/Number;当其判断引用类型时,返回值只有Object/Function,
你不知道它到底是一个Object对象,还是数组等(这句不太理解);
2. instancof 判断规则: A instanceof B, 沿着A的__proto__属性查找创建对象A的函数的原型;
沿着B的prototype属性查找B的函数;如果两条线能找到同一个引用,
或是同一个函数对象,那么返回true;如果找到最终点却还是为重合,返回false.
例: 1. console.log(Object instanceof Function); //返回true
解释: Object的函数原型为Function,Function的prototype指向Function,故返回true.
2. console.log(Function instanceof Object); //返回true(不太理解)
解释: Function的函数原型为Function,Object的prototype指向Object,而函数是对象的一种,故返回true.
3. console.log(Function instanceof Function);//返回true
解释: Function的函数原型为Function,Function的prototype指向Function,故返回true
-
-