JavaScript中的原型与原型链全解析

prototype

只要创建一个函数,就会自动的为这个函数创建一个prototype属性,这个属性是一个指针指向函数的原型对象
在默认情况下,所有原型对象都会自动获得一个constructor属性(是一个指针),指向原来的函数。

原型对象有什么好处?

让所有的对象实例共享属性和方法

function person(name) {
    this.sayName = new Function("alert(this.name)")
}

var person1 = new person('david');
var person2 = new preson('leslie');

console.log(person1.sayName == person2.sayName) //false

我们在创建对象时,希望所有的对象实例应该共享构造函数中的属性和方法,但是使用构造函数声明对象,不同实例上的同名函数是不相等的,所以需要通过原型模式来解决。

function person() {

}

person.prototype.name = 'jackson'
person.prototype.sayName = function() {
    alert(this.name)
}

var person1 = new person()
var person2 = new person()

console.log(person1.sayName == person2.sayName) //true

使用原型对象,所有的对象实例会共享原型对象中的实例和方法

proto

上面说的prototype是每个函数都有的属性,而**__proto__则是每个对象实例都有的属性**,有时也叫也叫[[Prototype]]
在创建对象实例时,自动创建__proto__属性指向原型对象

上图中的两个实例,都包含上述所说的__proto__,并指向原型对象

上面说到,不同的实例是共享所有原型对象中的属性和函数的,那如果该实例重写了原型对象中的属性时,就会将其屏蔽(屏蔽而不是覆盖!),即这个属性是这个实例所独有的。

  1. 那解析器是怎么解析的呢?
  • 当代码读取对象的某个属性或者对象时,先在实例中搜索,若找到,直接返回;若没找到,则再次搜索实例的__proto__指向的原型对象,若找到,返回。
    这也是多个对象实例共享原型中的属性和方法的基本原理。

使用hasOwnProperty()可以检测一个属性是存在在实例中,还是存在在原型中。当其存在在实例中,返回true,反之返回false。

JS中创建对象的三种方式

之所以将其分为三种不同的方式,也是由于其__proto__指向的对象不同。

字面量方式

var obj1 = { name: 'obj1';}
var obj11 = new Object( {name: "obj1";} )

对象的原型链指向Object

使用显式构造函数(构造器方式)

var M = function(name) {
    this.name = name
}
var obj2 = new M();

使用Object.create

var P = { name: 'obj3' }
var obj3 = Objecr.create(P)

原型链

利用原型让子对象继承父对象的属性和方法,这样层层递进,就形成了原型链。

示例代码:

function superType() {
    this.property = true //创建父构造函数,包含的实例属性会被继承到子原型对象中
}

superType.prototype.getSuperValue = function () {
    return this.property //父原型对象中的方法,不会被继承到子原型对象中,而是共享
}

function subType() {
    this.subproperty = false //创建子构造函数
}

subType prototype = new superType() //继承 !important

subType.prototype.getSubValue = function() {
    return this.subproperty
}

var instance = new subType() //实例
console.log(instance.getSuperValue()) //true

在前面说过读取属性时,先搜索实例对象,再网上搜索实例原型。
在通过原型链实现继承的情况下,仍然按照上述方法进行搜索:

  1. 搜索实例
  2. 搜索子原型对象subType.prototype
  3. 搜索父原型对象superType.prototype

加上JS默认对象Object


JS中的所有对象都是Object的实例,因此默认原型对象都会包含__proto__指向Object.prototype。

确定原型和实例之间的关系

instanceof

instace instanceof Object  //true
instace instanceof superType //true
instace instanceof subType //true

isPrototypeOf()

Object.prototype.isPrototypeOf(instance) //true
superType.prototype.isPrototypeOf(instance) //true
subType.prototype.isPrototypeOf(instance) //true

参考资料:

全部评论

相关推荐

感觉这一周太梦幻了,就像一个梦,很不真实~~~感觉这个暑期,我的运气占了99成,实力只有百分之一4.15上午 腾讯csig 腾讯云部门,面完秒进入复试状态4.16下午 美团优选供应链部门,4.18上午发二面4.17晚上 阿里国际一面,纯拷打,面完我都玉玉了4.18下午 阿里国际二面,是我们leader面的我,很轻松~~4.18晚上 约了hr面4.19上午 hr面,下午两点口头oc4.19晚上 意向书说起来我的暑期好像一次都没挂过~~~~~难道我是天生面试圣体?----------------------------------------------------------------------六个月前,我还是0项目0刷题,当时想的是先把论文发出来再去找实习。结果一次组会,老师打破了我的幻想(不让投B会,只让投刊或者A)我拿头投啊!!!然后就开始物色着找实习,顺便做完了mit的6.s081,但是基本上还是没刷过题目-----------------------------------------------------------------------11月  一次偶然的机会,面进了某个耳机厂的手环部门,大概是做嵌入式的,用的是CPP。12月 莫名其妙拿到了国创的面试机会,0基础四天速成java基础!居然也给我面过了hhhhh,可能是面试没写题吧入职国创后的几个月,一直没活,天天搁那看剧,都快忘了还有暑期实习这回事了~~~~命运的齿轮在2.26开始转动,因为这一天美团开了,我开始慌了,因为那时的我什么都不会。lc,八股,sql全部是0进度。然后就开始了女娲补天,上班刷题,下班继续做之前的开源,顺便学一学八股。3月到现在,lc也刷到快200了,一天最多提交了47次~~~~~~~~~~八股根据别人的面经总结和博客,写了快十万字的笔记~~~~~~~~~~简历上的实习经历和开源,也努力去深挖了,写了几万字的记录~~~~~~所以面试的时候,基本上都能cover了,面试官问到的基础基本都会,不基础的我就把他往我会的地方引。结果好像还不错,基本上每个面试官评价都挺好的emmmmmmmm
投递阿里巴巴等公司10个岗位
点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务