彻底理解原型 原型链
原型和原型链也是经常被面试问到的问题,其实原型,原型链涉及问题较多,本文也延展了几个面试中常问的知识点,文章不长,耐心看完肯定会有收获。
创建对象的几种方法
- 字面量创建
var n={name:1};
var n2=new Object({name:1});
- 构造函数创建
var M=function(){
this.name=1
};
var n=new M()
- Object.create创建
var P={name:1};
var n=Object.create(P)
- 打印一下结果
- 其他创建对象的方法就不一一列举了,有兴趣的可参考《创建对象的几种方式》
原型、构造函数、实例、原型链
- 先看图
- 再上代码:
//字面量创建
var o1={name:'tom'}
var o2=new Object({name:'bob'});
//构造函数
var M=function(name){
this.name=name
}
var o3=new M('tom');
//object.create
var p={name:'tom'};
var o4=Object.create(p)
-
任何一个函数,只要被new了以后,就是构造函数,而new出来的被称之为实例。任何函数都可以当作构造函数。
-
函数中都有一个prototype属性,申明一个函数时候就会有个prototype属性,这个属性会初始化一个空对象,也就是原型对象。
-
原型对象中会有一个构造器:constructor,它默认会指向你申明的那个函数。结合上面写的创建对象的例子以及结合关系图验证一下:
-
可以看到结果:M.prototype.constructor==M结果为true,也就验证了上面关系图。
-
再次验证一下实例与他们的关系:
原型对象存在的作用
- 先上例子
function Person(name,age){
this.name=name;
this.age=age;
this.eat=function(){
console.log(age+"岁的"+name+"在吃饭")
}
};
let Tom=new Person("Tom",24);
let Bob=new Person("Tom",24);
console.log(Tom.eat===Bob.eat); //flase
-
可以看到对于同一个函数,new出来的实例,都会开出新的一块堆区,所以例子中Tom和Bob的eat是不同的。
虽然拥有自己的的东西(比如房子,车子)是很好的,但它也有不好的地方,毕竟一共就那么大的地方(内存),你要 一直建立房子,会导致地方不足(内存不足)。 -
所以要想个方法,建立共享库的的对象(例如把楼房建高),这样就可以在需要的时候调用一个类似共享库的对象(社区),让实例能沿着某个线索找到它的归处。
function Person(name,age){
this.name=name;
this.age=age;
};
// 通过构造函数的 Person 的 prototype 属性找到 Person 的原型对象
Person.prototype.eat=function(){
console.log("吃饭")
};
let Tom=new Person("Tom",24);
let Bob=new Person("Tom",24);
console.log(Tom.eat===Bob.eat); //true
- 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又 会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的镜头就是Object.prototype
instanceof的原理
- instanceof 可以正确的判断对象的类型,因为内部机制是通过判断对象的原型链中是不是能找到类型的 prototype
console.log([] instanceof Array); // true
console.log(function(){} instanceof Function); // true
console.log({} instanceof Object); // true
new运算符中都干了什么
-
创建一个简单空对象
-
链接该对象到另一个对象(原型链)
-
将步骤1新创建的对象作为this的上下文
-
如果该函数没有返回对象,则返回this
-
如果return则返回return的值
var new2=function(func){
var o=Object.create(func.prototype);
var k=func.call(o);
if(typeof k =='object'){
return k
}else{
return o
}
}
总结
如有错误,欢迎指正,如果对你有帮助,记得点赞收藏!