JavaScript——原型链

1.在js中,所有对象都有自己的原型对象(prototype)。一方面,任何一个对象,都可以充当其他对象的原型;另一方面,由于原型对象也是对象,所以它也有自己的原型。因此,就会形成一个“原型链”:对象到原型,再到原型的原型...直到null为止。

            function fn() {
				this.eye = 2
				this.life = 1
			}
			function fm() {
				this.name = "xiaozhang"
				this.age = 21
			}
			var f1 = new fn()
			//将f1对象作为fm的原型对象
			fm.prototype = f1
			// 上一步执行之后,再通过fm创建的对象就具有f1的属性
			var f2 = new fm()
			console.log(f2)
			console.log(f2.life)
			console.log(f2.eye)

结果:

2.当读取某个对象的属性时,先在对象本身查找,如果没有就到对象的原型对象上查找,如果对象的原型对象也没有,就到原型对象的原型对象上找,以此类推......

            function fn() {
				age = 20
			}
			fn.prototype.name = "xiaozhang"
			var f1 = new fn()
			console.log(f1.name)

直到找到null都没有,那么就返回undefined

            function fn() {
				age = 20
			}
			fn.prototype.name = "xiaozhang"
			var f1 = new fn()
			console.log(f1.a)

 

 3.如果对象本身和它的原型对象都定义了一个同名属性,读取时优先读取对象本身的属性。

            function fn() {
				this.age = 20
			}
			fn.prototype.age = 30
			var f1 = new fn()
			console.log(f1.age)

 

4.对象给一个成员存值时 ,无论其原型链上是否有这个成员 都会把更新或者添加这个成员在对象自己的内存中 ,不会操作原型对象

            function fn() {
				this.name = "xiaozhang"
			}
			fn.prototype = {age:30}
			var f1 = new fn()
			f1.age = 20
			console.log(f1)

 

5.系统内置构造函数:Object、 Function、 Array、 Date等; 系统内置的构造函数的原型属性不可以直接替换(代码会被静默) 但是可以添加或者重写其原型对象的成员;自定义的构造函数的原型属性可以随便操作

            // 代码不会报错,但是不会执行这一句
			Array.prototype = {a:20}
			// 在Array的原型对象中添加了一个age属性,值为22
			Array.prototype.age = 22
			// 此后创建的数组都能访问到age属性
			var arr = [1,2,3]
			console.log(arr.__proto__)
			console.log(arr.age)

6.笔试题1 

            Object.prototype.life = 1 
			Function.prototype.life = 2
			function fn() {
				this.name = "karen"
			}
			var f1 = new fn()
			console.log(f1.name,f1.life) 
			console.log(fn.life,fn.name)

结果:

分析:第一步,最开始就给系统内置构造函数Object和Function的原型对象添加了一个life属性,值分别为1和2;所以之后创建的对象和函数都能访问到life属性。

第二步,创建了一个函数fn,添加一个name属性为karen

第三步,使用new关键字:1.创建空对象 2.函数中的this指向创建的空对象 3.函数的返回值为基本数据,所以表达式的值就是创建的对象

第四步,因为this指向的是创建的对象,因此f1.name=karen;由于表达式得到的是对象,所以f1能访问的是Object的原型对象,所以f1.life=1

第五步,因为fn是定义的一个函数,而一开始就为所有函数的原型对象添加了life属性,值为2,所以fn.life=2;而函数有默认的name属性,就是函数名,因此fn.name=fn

7.笔试题2

            function Parent() {
				this.a = 1;
				this.b = [1, 2, this.a];
				this.c = {
					demo: 5
				};
				this.show = function() {
					console.log(this.a, this.b, this.c.demo);
				}
			}

			function Child() {
				this.a = 2;
				this.change = function() {
					this.b.push(this.a); 
					this.a = this.b.length;
					this.c.demo = this.a++;
				}
			}
            Child.prototype = new Parent();
            var parent = new Parent();
            var child1 = new Child();
            var child2 = new Child();
            child1.a = 11;
            child2.a = 12;
            parent.show();
            child1.show();
            child2.show();
            child1.change();
            child2.change();
            parent.show();
            child1.show(); 
            child2.show();

结果:

分析:         

            1.Child.prototype = new Parent();将new Parent()作为Child函数的原型对象,也就是用Child函数创建的对象都能访问到new Parent()的属性;Child.prototype={a:1,b:[1,2,1],c:{demo:5},show:function(){console.log(this.a,this.b,this.c.demo)},__proto__:{}}
            2.var parent = new Parent();通过new关键字使用Parent函数创建一个新对象,this指向创建的对象,创建的对象能够访问到Parent的属性
            3.var child1 = new Child();var child2 = new Child();分别使用new关键字使用Child函数分别创建child1和child2对象,this指向新创建的对象,并且这两个对象的原型对象是new Parent()
            4.child1.a = 11; 在child1中添加一个属性a,并赋值为11.
                    child2.a = 12;在child2中添加一个属性a,并赋值为12.
            5.parent.show();调用parent对象中的show方法,打印出1 [1,2,1] 5
            6.child1.show();由于child1对象中没有show方法,所以到其原型对象new Parent()中找;并打印a,b,c.demo的值,但是由于child1里面有a属性,所以就打印它本身的a的值,其余没有的就打印原型对象中对应的值;因此打印 11 [1,2,1] 5
                    child2.show()同理可得 ,打印12 [1,2,1] 5
            7.child1.change();执行change方法,this指向的是child1。this.b.push(this.a);由于原型对象不能修改但是可以操作,且这一步并没有修改原型对象,只是向原型对象的b属性中添加了一个数据,此时b就变为了[1,2,1,11]。this.a = this.b.length;给child1自己添加/更新a属性 值为child1的原型对象的属性b的长度,为4。this.c.demo = this.a++;先取a的值为4,再赋值给原型对象中的c.demo,最后a再加1变为5.
            child2.change();同理,先再向原型对象的b中增加了a的值12,b就变为了[1,2,1,11,12];并且a又重新赋值为b.length的值,为5;然后再a再加1变为6.
            8.parent.show(); 还是打印 1 [1,2,1] 5
                    child1.show(); 打印 5 [1,2,1,11,12] 5
                    child2.show(); 打印 6 [1,2,1,11,12] 5

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z_小张同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值