原型和原型链
定义:每一个函数对象都有一个prototype ,它指向一个对象–>通过该函数创建的实例对象原型,所以成为原型对象,原型对象的prototype属性有一个constructor属性,指向它的构造函数,每一个对象都有一个__proto__属性,它指向它的构造函数的原型对象,所有的原型对象都是Object()的实例,每一个构造函数都是Function 的实例
原型:javascript每创建出一个对象都会有一个对象的原型,是对象共享原型的属性和方法,原型存在就是共享方法,减少不必要的内存消耗
原型链
在jsvascript中,每个对象通过__proto__属性指向它的原型对象,这个原型对象也是对象,所以也有__proto__,一直到null为止,这种一级一级的链结构就叫做原型链

function Fun(){}
let a=new Fun
console.log(a.__proto__===Fun.prototype) //true
console.log(Fun.prototype.constructor===Fun) //true
Function.prototype.names='张三'
Object.prototype.age=12
console.log(a.names)//undefined
console.log(a.age)//12
console.log(Fun.names)//张三
console.log(Fun.age)//12
a.proto===Fun.prototype
Fun.prototype.proto===Object.prototype
Fun.proto===Function.prototype
Function.prototype.proto===Object.prototype
a的原型链上找不到name 的属性,可以在Fun 的原型链上找到name 和age 的属性
原型和原型链的练习题
function Fun(){}
Fun.prototype.n=12
let a=new Fun
Fun.prototype={n:14,m:11}
let b=new Fun
console.log(a.n,a.m,b.n,b.m)
12 undefined,14,11
答案是不是和你预想的不一样?,实例的__proto__指向是原来的内存地址,Fun.prototype={}对象会重新开辟一个内存空间,b 实例对象指向的跟a 指向的地址就不一样了
function Fun(){}
Fun.prototype={n:14,m:11}
let b=new Fun
Fun.prototype.m=13
Fun.prototype.n=13
console.log(a.n,a.m,b.n,b.m)
function Fun(){}
Fun.prototype={n:14,m:11}
let a=new Fun
Fun.prototype={n:11,m:14}
let b=new Fun
console.log(a.n,a.m,b.n,b.m)
12 undefined 13,13
14,11,11,14
这次答案对了吗?第一个直接修改属性内存地址是不会更改的,用对象的形式更改才会修改地址
var F =function(){}
Object.prototype.a=function(){
console.log("1")
}
Function.prototype.b=function(){
console.log('2')
}
var f=new F()
F.a()
F.b()
f.a()
f.b()
1,2,1,f.b is not a function
这道题和前面一道是类似的,机智的小伙伴答对了吗?
f.proto===F.prototype
F.prototype.proto===Object.prototype
F.proto===Function.prototype
Function.prototype.proto===Object.prototype
原型链是从__proto__上进行查找的,f 只能调用F.prototype 上的方法
function A(){}
function B(a){this.a=a}
function C(a){if(a){this.a=a}}
A.prototype.a=1
B.prototype.a=1
C.prototype.a=1
console.log(new A().a)
console.log(new B().a)
console.log(new C(2).a)
1,undefind 2
A 的实例对象本身没有a,从A.prototype 上取1
B的实例对象本身有a ,但因为在new的时候没有传参,a 的值是undefined
C 的实例对象本身有a ,且a 的值是2
function Child(){
this.a=2;
this.change=function(){
console.log(this.a)
}
}
var child1=new Child()
child1.a=11
child1.change()
11
在new 的时候,创建了实例对象,并指向函数体child1={a:2,change:f}并且this指向实例对象,在修改child1的a值之后,change 里面的this.a 也会相应发生改变
function Person(){
this.a=5
this.b=[1,3,this.a]
}
function Child(){
this.a=2;
this.change=function(){
console.log(this.a,this.b)
}
}
Child.prototype=new Person()
var child1=new Child()
child1.a=11
child1.change()
11,[1,3,5]
Child.prototype在new的时候 Child.prototype={a:5,b:[1,3,5]}
child1:{a:11,change:f},change()的时候,a:11,b:[1,3,5]
function Person(){
this.a=5
this.b=[1,3,this.a]
this.c={demo:3}
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 Person()
var person=new Person()
var child1=new Child()
var child2=new Child()
child1.a=4
child2.a=2
person.show()
child1.show()
child2.show()
child1.change()
child2.change()
person.show()
child1.show()
child2.show()
5,[1,3,5],3
4,[1,3,5],3
2,[1,3,5],3
5,[1,3,5],3
5,[1,3,5,4,2],5
6,[1,3,5,4,2],5
小伙伴答对了吗?
Child.prototype=new Person() ->Child.prototype={a:5,b:[1,3,5],c:{demo:3},show:f}
var person=new Person()->person={a:5,b:[1,3,5],c:{demo:3},show:f}
var child1=new Child()->child1={a:2,change:f}
var child2=new Child()->child2={a:2,change:f}
child1.a=4->child1={a:4,change:f}
child2.a=2->child2={a:2,change:f}
child1.change()->child1={a:5,change:f}Child.prototype:{a:5,b:[1,3,5,4],c:{demo:4},show:f}
child2.change()->child1={a:6,change:f}Child.prototype:{a:5,b:[1,3,5,4,2],c:{demo:5},show:f}
function Person(){
this.a=5
this.b=[1,3,this.a]
this.c={demo:3}
this.show=()=>{
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 Person()
var person=new Person()
var child1=new Child()
var child2=new Child()
child1.a=4
child2.a=2
person.show()
child1.show()
child2.show()
child1.change()
child2.change()
person.show()
child1.show()
child2.show()
5,[1,3,5],3
5,[1,3,5],3
5,[1,3,5],3
5,[1,3,5],3
5,[1,3,5,4,2],5
5,[1,3,5,4,2],5
关于原型链的题目分享到此了,有兴趣的小伙伴可以留言讨论哦
本文深入探讨JavaScript中的原型和原型链概念,包括每个函数对象的prototype属性、对象的__proto__属性、原型链的形成以及如何通过原型链查找属性。通过实例解析了原型链的工作原理,如属性查找、原型链的修改对实例的影响,并提供了相关练习题加深理解。
359

被折叠的 条评论
为什么被折叠?



