javaScritp 中prototype属性继承原理详解,javaScript中instanceof运算符运算原理详解,看图说话

                 

           转载请说明出处:http://blog.csdn.net/liuqiwen0512/article/details/8095306

             上一篇文章我们说了jQuery  运用jQuery.fn.init.prototype = jQuery.fn;巧妙的避开了 instanceof 的运算。

       要解释这个问题就需要先了解prototype属性的继承原理,比如toString方法,我们创建一个对象不用给对象

       添加toString方法照样可以用。这是为什么,是创建对象的时候js自动给对象添加了toString方法,还是通过上面途径

       找到了toString方法。这里可以告诉你我们用new关键字创建出来的对象要是你没给它添加toString属性的话,

       那么它调用的就是Object对象的prototype.toString。这是为什么,有的童鞋说是继承,但是它又是怎样继承的,

       toString到底放在哪,看完这篇文章你就明白了。还有一个问题就是instanceof运算符到底是怎么运算的,

       它的依据和原理是什么,同样看完这篇文章你也就明白了。

 

protype继承原理:

             其实我们用function关键字声明的方法,在后台js会把他们创建成Function对象。这个对象中有两个属性,一个是prototype

             这个属性是显属性也就是说我们可以访问的属性。还有一个属性就是__proto__这个属性是隐式的,也就是说默认

             情况下我们不可以访问,而且这个属性在个浏览器的表示可能还不一致,默认情况下是__proto__。这个属性在chrome

             浏览器是可以访问的,但是在IE下就不可以访问,不知道是IE不让访问,还是表示不一样,没研究。

             prototype属性是一个指针,指向一个实例化的Object对象。这个对象默认有两个属性,一个是显属性constructor,

             这个属性是指向prototype属性所在的构造函数,这样prototype属性所指向的Object对象和构造函数就形成了循环

             指向。还有一个隐属性默认是__proto__指向它的父对象也就是js内置的Object对象的prototype属性所指向的

             一个实例化的Object对象。

 

下面看例子说话:

function Person(){
      this.name="刘奇文";
      this.age=22;
}
	Person.prototype={
		   showName:function(){
			  console.log(this.name);
		   },
		   name:"liuqiwen"
	}
function Man(){
      this.name="刘奇文man";
      this.age=22;
}
	Man.prototype=Person.prototype;

var man1=new Man();
console.log(man1.name);//结果:刘奇文man
man1.showName();//结果:刘奇文man
delete man1.name;//删除实例中的name属性
console.log(man1.name);//结果:liuqiwen
man1.showName();//结果:liuqiwen
console.log(man1.constructor);//结果:function Object() {[native code]}
console.log(man1 instanceof Man);//结果:true
console.log(man1 instanceof Person);//结果:true
console.log(man1 instanceof Object);//结果:true

上面代码解释:

             创建一个构造函数Person,给构造函数添加两个属性。然后再初始化构造函数的原型链prototype属性,

       给prototype添加两个属性,在创建一个构造函数Man,给构造函数添加两个属性。然后再初始化 构造函数

      的原型链prototype属性,让prototype属性等于Person的prototype属性,也就是说这两个构造函数的prototype

      指向的是同一个Object对象。然后创建一个man1的一个实例,调用man1的name属性得到结果正是实例中

      属性的值,调用man1的showName方法得到也是实例中属性值结果都正确,我们再删除实例中name属性

      我们再重复上面的操作发现结果是原型链中属性的值,我们再调用man1的constructor属性,这个属性

      上面已经说过是得到这个实例的构造函数的引用,上面我们既没有给实例定义这个属性,原型链中也

      没有这个属性,那么调用这个属性得到的值是哪里来的,为什么还是Object。

对象属性的查找顺序:

             其实我们没有给prototype属性赋值时,prototype属性默认指向的Object对象是有

      constructor这个属性的,由于这个属性是显的是我们可控制的,所以当我们给prototype属性初始化

      时是让它指向了另一个对象,而这个对象中没有此属性,我们也可加上这个属性。当对象在实例中

      没有找到要调用的属性,那么他会从他的隐属性__proto__所指向的原型链中查找,如果还没找到,

       那么他会继续查找原型链中的隐式__proto__属性所指向的对象,

      也就是实例的父对象Object对象的原型链,所以返回值是Object的构造函数。

总结:实例对象属性查找顺序是   实例对象内部---->构造函数原型链---->实例对象父对象的原型链。

 

instanceof运算符:

        上面man1 instanceof Man结果为true,运算符先运算Man.prototype然后再查找man1中的__proto__

        所指向的Object是否为Man.prototype。由于Person.prototype和Man.prototype指向的是同一个Object

        所以man1 instanceof Person结果为true。man1 instanceof Object由于man1中的__proto__指向的

        不是Object.prototype所以运算符会继续查找__proto__指向的对象中的__proto__属性,也就是实例

         父对象的prototype指向的对象,Object是实例man1的父对象所以运算结果为true。

 

通过关系图来了解他们之间的关系

继承关系图:

 下篇分析下构造函数和Object之间的关系 ,js内置对象之间的关系。

上图中 Function 和 Object之间的关系有些地方好像不太对,

还需研究,如果哪位仁兄知道的话,请赐教。

 转载请说明出处:http://blog.csdn.net/liuqiwen0512/article/details/8095306

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值