JS重点整理之JS原型链彻底搞清楚


对象

要清楚原型链,首先要弄清楚对象:

  • 普通对象

    • 最普通的对象:有__proto__属性(指向其原型链),没有prototype属性。
    • 原型对象(person.prototype 原型对象还有constructor属性(指向构造函数对象))

  • 函数对象:
    • 凡是通过new Function()创建的都是函数对象。
                          拥有__proto__、prototype属性( 指向原型对象)。

                          FunctionObjectArrayDateString、自定义函数

                          特例: Function.prototype( 是原型对象,却是函数对象,下面会有解释 )
函数对象
function f1(){};
var f2 = function(){};
var f3 = function("n1","n2","return n1+n2");

console.log(typeof f1);  //function
console.log(typeof f2);  //function
console.log(typeof f3);   //function
console.log(typeof Object);   //function
console.log(typeof Array);   //function
console.log(typeof String);   //function
console.log(typeof Date);   //function
console.log(typeof Function);   //function

Array是函数对象,是Function的实例对象,Array是通过newFunction创建出来的。因为Array是Function的实例,所以Array.__proto__ ===  Function.prototype


普通对象
var o1 = new f1(); 
var o2 = {};       
var o3 = new Object(); 

console.log(typeof o1);  //Object
console.log(typeof o2);   //Object
console.log(typeof o3);   //Object

原型对象


        每创建一个函数都会有一个prototype属性,这个属性是一个指针,指向一个对象(通过该构造函数创建实例对象的原型对象)。原型对象是包含特定类型的所有实例共享的属性和方法。原型对象的好处是,可以让所有实例对象共享它所包含的属性和方法。
        第一块中有提到,原型对象属于普通对象。Function.prototype是个例外,它是原型对象,却又是函数对象,作为一个函数对象,它又没有prototype属性。
function person(){};

console.log(typeof person.prototype) //Object
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype) // 特殊 Function
console.log(typeof Function.prototype.prototype) //undefined 函数对象却没有prototype属性

解释:

     functionperson(){};

        其实原型对象就是构造函数的一个实例对象。person.prototype就是person的一个实例对象。相当于在person创建的时候,自动创建了一个它的实例,并且把这个实例赋值给了prototype。

 function person(){};
var temp = new person();
person.prototype = temp;

function Function(){};
var temp = new Function();
Function.prototype = temp; //由new Function()产生的对象都是函数对象

        从一张图看懂原型对象、构造函数、实例对象之间的关系

function Dog(){};

Dog.prototype.name = "小黄";
Dog.prototype.age =  13;
Dog.prototype.getAge = function(){
	return this.age;
}

var dog1 = new Dog();
var dog2 = new Dog();

dog2.name = "小黑";
console.log(dog1.name); // 小黄 来自原型
console.log(dog2.name); // 小黑 来自实例



//图中的一些关系
dog1.__proto__ === Dog.prototype

Dog.prototype.__proto__ === Object.prototype //继承Object 下面原型链说

dog1.__proto__.__proto__ === Object.prototype

Dog.prototype.constructor === Dog 

Dog.prototype.isPrototypeOf(dog1)

获取对象的原型
dog1.__proto__  //不推荐
Object.getPrototypeOf(dog1) === Dog.prototype   //推荐


原型链

原型链是实现继承的主要方法。

 

先说一下继承,许多OO语言都支持两张继承方式:接口继承、实现继承。

|- 接口继承:只继承方法签名

|- 实现继承:继承实际的方法

由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承,而实现继承主要是依靠原型链来实现。


原型链基本思路:

利用原型让一个引用类型继承另一个引用类型的属性和方法。

每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针(constructor),而实例对象都包含一个指向原型对象的内部指针(__proto__)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针(__proto__),另一个原型也包含着一个指向另一个构造函数的指针(constructor)。假如另一个原型又是另一个类型的实例……这就构成了实例与原型的链条。


原型链基本思路(图解):



举例说明:

function animal(){
	this.type = "animal";
}
animal.prototype.getType = function(){
	return this.type;
}

function dog(){
	this.name = "dog";
}
dog.prototype = new animal();

dog.prototype.getName = function(){
	return this.name;
}

var xiaohuang = new dog();

//原型链关系
xiaohuang.__proto__ === dog.prototype
dog.prototype.__proto__ === animal.prototype
animal.prototype.__proto__ === Object.prototype
Object.prototype.__proto__ === null
 
   

图解:


详细图


从xiaohuang这个实例,看出整个链条


总结:

Xiaohuang这个Dog的实例对象继承了Animal,Animal继承了Object。




  • 27
    点赞
  • 93
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值