手机版

学习javascript面向对象理解javascript原型和原型链

时间:2021-09-19 来源:互联网 编辑:宝哥软件园 浏览:

先看图梳理一下。

一、基本概念【原型链】每个构造函数都有一个对象,原型对象包含一个指向构造函数的指针,实例包含一个指向原型对象的内部指针。然后,如果原型对象等于另一个原型的实例,那么原型对象将包含指向另一个原型的指针,相应地,另一个原型也将包含指向另一个构造函数的指针。如果另一个原型是另一个原型的实例,那么上述关系仍然成立。如此进步,它构成了一连串的例子和原型。[原型对象]该对象包含可由特定类型的所有实例共享的属性和方法。所有引用类型默认继承Object,这种继承是通过原型链实现的。所有函数的默认原型都是对象的实例,因此默认原型将包含一个指向Object.prototype的内部指针,这就是为什么所有自定义类型都将继承toString()和valueOf()方法。【构造函数】构造函数与其他函数的区别在于调用方式不同。一般来说,函数只要被新的操作符调用,就可以作为构造函数使用。如果不是被新的操作符调用,和普通函数没什么区别。【注意】javascript内置的用户自定义函数和构造函数都可以作为构造函数使用。【如何编写构造函数】构造函数应该总是以大写字母开头,而非构造函数应该以小写字母开头。这种做法借鉴了其他OO语言,主要是为了区别于ECMAScript中的其他函数。因为构造函数本身是一个函数,所以只能用来创建对象。[构造函数的三种使用场景] [a]用作构造函数。

var Person=new Person(‘Nicholas’,29岁,‘软件工程师’);person . SayName();[b]作为正常的函数调用。

人(“格雷格”,27岁,“医生”);//添加到window window . SayName();//“Greg”[c]在另一个对象的作用域中被调用。

var o=新对象();人称称呼(o,‘克里斯汀’,25岁,‘护士’);o . SayName();//‘Kristen’[prototype属性]只要创建了一个新的函数,就会根据一组特定的规则为该函数创建一个prototype属性,这些规则指向该函数的原型对象。[注意]只有函数有原型属性,而对象没有原型属性[构造函数属性]。默认情况下,所有原型对象都将自动获得一个构造函数属性,该属性包含一个指向原型属性所属函数的指针。[注意]创建自定义构造函数后,默认情况下,其原型Object只获取构造函数属性,而其他方法是从Object [_proto_和[[prototype]]继承而来的。当调用构造函数创建新实例时,实例内部将包含指向构造函数原型对象的指针(内部属性)。ECMA-262版本5调用这个指针[[原型]]。虽然[[prototype]]在脚本中是以标准方式访问的,但是firefox\safari\chrome支持每个对象上的一个attribute _ prototype在其他实现中,脚本完全看不到这个属性。这种连接存在于实例和构造函数的原型对象之间,但不存在于实例和构造函数之间。2.基本操作【原型链查询】每当代码读取一个对象的属性时,都会进行搜索,目标是给定名称的属性。首先,搜索从对象实例本身开始。如果在实例中找到具有给定名称的属性,则返回该属性的值。如果没有找到,继续搜索指针指向的原型对象,在原型对象中找到给定名称的属性,如果找到了,返回属性值。[添加实例属性]当一个属性被添加到一个对象实例时,该属性将屏蔽与原型对象中保存的名称相同的属性;换句话说,添加这个属性只会阻止我们访问原型中的那个属性,而不会修改那个属性。即使此属性设置为null,它也只会在实例中设置,并且它与原型的连接不会恢复。但是,使用delete操作符可以完全删除实例属性,这样我们就可以重新访问原型中的属性。[Prototype的动态]因为在原型中查找值的过程是一个搜索,所以我们对原型对象所做的任何修改都可以立即从实例中反映出来,即使首先创建实例,然后修改原型。[注意]不建议在生产程序中修改原生对象的原型。

函数Person(){ };var friend=new Person();person . prototype . SayHi=function(){ alert(' hi ');} friend . SayHi();//' hi '[重写原型]在调用构造函数时,它会为实例添加一个[[prototype]]指向原始原型的指针,将原型修改为另一个对象会切断构造函数与原始原型之间的连接。实例中的指针只指向原型,而不指向构造函数。Iii .基本方法[1]isPrototypeOf():判断实例对象和原型对象是否存在于同一个原型链中。只要原型已经出现在原型链中,就可以说是从原型链中派生出来的实例的原型。

函数Person(){ };var Person 1=new Person();var person2=新对象();console . log(person . prototype . is rototypeof(person 1));//true console . log(object . prototype . isprototypeof(person 1));//true console . log(person . prototype . is rototypeof(person 2));//false console . log(object . prototype . isprototypeof(person 2));//true[2]ECMAScript5添加了Object.getPrototypeOf():方法。此方法返回[[原型]]的值。

函数Person(){ };var Person 1=new Person();var person2=新对象();console . log(object . getprototypeof(person 1));//Person { } console . log(object . getprototypeof(Person 1)==Person . prototype);//true console . log(object . getprototypeof(person 1)==object . prototype);//false console . log(object . getprototypeof(person 2));//object { }[3]hasown property():检测实例中是否存在属性。

函数Person(){ Person。原型。名字='尼古拉斯';} var Person 1=new Person();//不存在实例中,但存在原型中控制台。日志(人1。hasown属性(' name ');//false/不存在实例中,也不存在原型中控制台。日志(人1。hasown属性(' no ');//假者1。名字='格雷格';控制台。日志(人1。姓名);//‘格雷格’控制台。日志(人1。hasown属性(' name ');//true删除人1。姓名;控制台。日志(人1。姓名);//‘尼古拉斯’控制台。日志(人1。hasown属性(' name ');//false [4]ECMAScript5的对象。getowntpropertysdescriptor():只能用于取得实例属性的描述符,要取得原型属性的描述符,必须直接在原型对象上调用对象。getowntpropertysdescription()方法

函数Person(){ Person。原型。名字='尼古拉斯';} var Person 1=new Person();人1。名字='库克';控制台。日志(对象。getowntpropertysdescriptor(person 1,“name”);//对象{value: 'cook ',writable: true,enumerable: true,configuration ble : true }控制台。日志(对象。getowntpropertysdescriptor(person。原型,‘名称’);//对象{value: 'Nicholas ',可写:真的,可枚举:真的,可配置: true}[5]in操作符:在通过对象能够访问给定属性时返回没错,无论该属性存在于实例还是原型中

函数Person(){ } var Person 1=new Person();人1。名字='库克';控制台。日志('个人1中的名称');//真控制台。日志('人。原型中的名称');//false var Person 2=new Person();人。原型。名字='库克';控制台。日志(人员2中的“姓名”);//真控制台。日志('人。原型中的名称');//真[6]同时使用hasOwnProperty()方法和在操作符,来确定属性是否存在于实例中

//hasOwnProperty()返回假的,且在操作符返回没错,则函数返回没错,判定是原型中的属性函数hasPrototypeProperty(对象,名称){返回!object.hasOwnProperty(name)(对象中的名称);}函数Person(){ Person。原型。名字='尼古拉斯';} var Person 1=new Person();控制台。日志(hasPrototypeProperty(person 1,“name”));//真人1。名字='库克';控制台。日志(hasPrototypeProperty(person 1,“name”));//false删除人1。姓名;控制台。日志(hasPrototypeProperty(person 1,“name”));//true删除人。原型。姓名;控制台。日志(hasPrototypeProperty(person 1,“name”));//false[7]ECMAScript5的Object.keys()方法:接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组[注意]一定要先新的出实例对象再使用该方法,否则为空

函数Person(){ Person。原型。名字='尼古拉斯';人。原型。年龄=29岁;Person.prototype.job="软件工程师";人。原型。SayName=function(){ alert(this。姓名);} };变量键=对象键(人。原型);console.log(键);//[]var P1=新人();p1.name=' Robp1。年龄=31岁;变量键=对象键(人。原型);console.log(键);//['姓名','年龄','工作,'说出名字']var p1Keys=object。凯斯(P1);控制台。日志(P1Keys);//['姓名','年龄][8]ECMAScript5的Object.getOwnPropertyNames()方法:接收一个对象作为参数,返回一个包含所有属性的字符串数组[注意]一定要先新的出实例对象再使用该方法,否则只有构造器

函数Person(){ Person。原型。名字='尼古拉斯';人。原型。年龄=29岁;Person.prototype.job="软件工程师";人。原型。SayName=function(){ alert(this。姓名);} };var key=对象。getowntpropertynames(person。原型);console.log(键);//['构造函数]var P1=new Person();var key=对象。getowntpropertynames(person。原型);console.log(键);//['构造函数','名称','年龄','作业,' sayName']希望本文所述对大家学习爪哇岛描述语言程序设计有所帮助。

版权声明:学习javascript面向对象理解javascript原型和原型链是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。