美文网首页
深入理解JS原型(你不知道的js)

深入理解JS原型(你不知道的js)

作者: 阿飞去捉小蝴蝶 | 来源:发表于2019-05-12 22:44 被阅读0次

[[Prototype]]

在js中,几乎所有对象在创建时,其[[Prototype]]属性都会被赋予一个非空的值,其实就是对其他对象的引用,可以用Object.getPrototypeOf(obj)或者obj.__proto__访问。(也有空值的情况),当试图引用对象的属性时,就会触发[[Get]]操作,[[Get]]操作默认第一步是检测对象本身是否有这个属性,如果不在就进行第二步,访问对象的[[Prototype]]链,🌰

原型关联

上图可以看出对象myObject是没有a属性的,但是由于myObject的[[Prototype]]关联到了对象anotherObject,所以属性访问成功的找到了值1,即myObject.__proto__ == anotherObject,如果原型链中也找不到这个属性,则返回undefined

使用for..in遍历对象时原理和查找[[Prototype]]链类似,任何可以通过原型链访问到,并且是可枚举的属性都会被枚举。使用in操作符检查属性是否存在于对象中时,都会查找整条原型链,无论属性是否可以枚举。

小结:通过各种语法进行属性查找时都会查找[[Prototype]]链,直到找到属性或者查找完整条原型链,原型链的终点,都会指向内置的Object.prototype,所有内置对象都源于这个Object.prototype对象

属性设置和屏蔽

给对象设置一个属性,并不仅仅是添加一个新属性和修改已有的属性,分4种情况,🌰

修改对象属性

以上面的🌰来说

1.若myObject对象中包含要修改的foo普通数据访问的属性,则这条赋值语句只会修改已有的属性值

2.若foo不直接存在于myObject对象中,[[Prototyoe]]链就会遍历,若原型链上找不到,foo属性就会被直接添加到myObject上

3.如果对象本身和原型链上都存在此属性,则myObject中包含的属性会屏蔽原型链上层所有的foo属性,原型链查找规则,只选择原型链最底层的属性

4.若此属性存在于原型链上层时,又分为3中情况

    1.若原型链上层的此属性是普通数据访问属性,并且此属性的writeable: true,那就会直接在myObject上添加一个名为foo的属性,它是屏蔽属性

    2.若原型链上层的此属性的writeable: false,那则无法修改已有属性或创建屏蔽属性,严格模式下会抛错

    3.若原型链上层的此属性是一个setter,那就调用这个setter,不会创建屏蔽属性,也不会重新定义foo这个setter

注意,一些操作会隐式的产生屏蔽,例如 ++


“类”

在js中根本不存在类,一切皆对象。

所有的函数默认有一个名为prototype的公有的且不可枚举的属性,会指向一个对象,我们习惯叫做该函数的原型(注意是函数),通过函数名.prototype属性引用来访问,所有应该更准确的说所谓的原型是一个被贴上函数名.prototype标签的对象。🌰

prototype属性是引用的一个对象

这个对象是什么?可以这么理解,通过调用 new Foo()创建的每个对象,最终被[[Prototype]]链接到“Foo.prototype“引用的对象

“构造函数”

上面例子的Foo.prototype还有一个constructor属性,翻译过来是构造的意思,但这是一个误解,实际上是这个属性引用的是对象的关联函数,这里是Foo。

比如说,var a = new Foo(),a.constructor == Foo,看上去a好像是a有一个constructor属性指向Foo,实际上只是.constructor属性也是被委托给Foo.prototype对象,而Foo.prototype.constructor默认是指向Foo的,但这个属性不是不可修改的,我们可以手动修改,

Foo.prototype对象的修改

实际上函数本身只是普通的函数,只是加了new关键字,new会劫持所有普通函数并用构造对象的形式来调用它。直白一点就是,仅当使用new时,函数会变成“构造函数调用”。

现在我们知道[[prototype]]机制就是存在于对象中的一个内部链接,它会引用其他对象,如果在对象上没有找到想要的属性或方法,引擎就会继续在[[prototype]]关联的对象上查找,以此类推,这一系列对象的链接被称为“原型链”

关于原型就介绍这么多,以后有新的感悟还会继续更新,希望大家给与指正和交流...

相关文章

  • JS原型

    最近一直在理解JS的原型------《你不知道的JS》--------《JS设计模式》 里面都讲JS的原型运作方式...

  • JS博客

    JS构造函数及new运算符 JS原型对象和原型链 函数作用域和作用域链 干货分享:让你分分钟学会JS闭包 深入理解...

  • 关于js原型Prototype的理解

    深入理解可参考首先说下什么是js原型:  js每声明一个function,都有prototype原型,protot...

  • js new 运行机制

    js手札--js中new到底做了些啥JS核心系列:理解 new 的运行机制深入理解 Javascript 运行机制及原型

  • 深入理解JS原型(你不知道的js)

    [[Prototype]] 在js中,几乎所有对象在创建时,其[[Prototype]]属性都会被赋予一个非空的值...

  • 2018-01-09 关于javascript原型链的思考 pl

    s 深入理解原型和原型链? 构造函数 理解原型和原型链 new的时候js都干了什么? 一个实现继承的demo 构造...

  • 廖雪峰JS小记

    (function(){})() 原型,原型链 浅谈Js原型的理解JS 原型与原型链终极详解 对象 对象:一种无序...

  • 深入理解JS 中原型和原型链

    JS 中原型和原型链深入理解 首先要搞明白几个概念: 函数(function) 函数对象(function obj...

  • 前端资料

    ES6新数据类型 Symbol . js变量提升函数提升 js this js 原型及原型链理解 new做了什么 ...

  • JS原型、原型链深入理解

    目录 原型介绍 初识原型 创建规则 初识Object 初识Function "prototype"和"_proto...

网友评论

      本文标题:深入理解JS原型(你不知道的js)

      本文链接:https://www.haomeiwen.com/subject/hemsoqtx.html