原型概念
说到原型,要理解构造函数,原型对象
function fn (){} // 构造函数就是声明函数
// 声明函数后,浏览器会自动在内存中创建一个对象{},这个对象叫原型对象

上图分析如下:
-
实例对象stu被创建后跟函数Student没啥关系
-
实例对象若有多个:stu1,stu2,stu3都会有__proto__属性指向同一个原型对象
-
显示原型:函数中prototype属性就叫做显示原型
-
隐式原型:实例对象中__proto__属性就叫做隐式原型
-
对象的隐式原型和函数的显示原型相等
const stu = new Student()
stu.__proto__ // {constructor:f} 隐式
Student.prototype // {constructor:f} 显示
Student.prototype.constructor // Student(){}
const stu1 = new Student()
const stu2 = new Student()
stu1.__proto__ === stu2.__proto__ // true
stu.__proto__ === Student.prototype // true
Student.__proto__ // () {}
stu.prototype // undefined
// 可以看出,只有函数才有显示原型
// 函数和对象都可以有隐式原型
Student.__proto__ === Function.prototype // true
// Student 其实是Function的实例,所以上式成立
Function.prototype === Function.__proto__ // true
// 这说明Function很特殊,自己的显示原型=自己隐式原型
typeOf Number // function
typeOf String // function
typeOf Object // function
typeOf Array // function
typeOf {} // obejct
Number instanceof Object // true
String instanceof Object // true
Object instanceof Object // true
Array instanceof Object // true
Number instanceof Function // ture
String instanceof Function // true
Object instanceof Function // true
Array instanceof Function // true
// 可以看出,Function和Object互相继承
原型链
任何对象直接调用方法,例如obj.foo(),在实例本身没有这个属性的情况下,都是从其__proto__属性上查找的,也就是从该对象的构造函数的prototype属性上查找。。
这里有一道典型的题目就是考对上面几条的理解,我们都知道Object.prototype.toString方法可以用来判断数据类型,那么用Object.toString可以吗。 答案是:不可以。 因为Object.toString是Object.proto.toString,也就是Function.prototype.toString,和Object.prototype.toString根本不是同一个函数。
