笔记-你不知道的JS-原型

1 [[Prototype]]

关于默许的 [[Get]] 操纵来讲,假如没法在对象自身找到须要的属性,就会继承接见对象的 [[Prototype]] 链

一切一般的 [[Prototype]] 链终究都邑指向内置的 Object.prototype。由于一切的“一般”(内置,不是特定主机的扩大)对象都“源于”(或许说把 [[Prototype]] 链的顶端设置为)这个 Object.prototype 对象,如:toString,valueOf,hasOwnProperty,isPrototypeOf

var anotherObject = { a:2};
// 建立一个关联到 anotherObject 的对象
var myObject = Object.create( anotherObject ); 
// myObject = { __proto__: {  a:2, __proto__: Object}};
myObject.a; // 2

属性屏障

给一个对象设置属性并不仅仅是增加一个新属性或许修正已有的属性值,如myObject.foo = “bar”;

假如 myObject 对象中包括名为 foo 的一般数据接见属性,这条赋值语句只会修正已有的属性值。

假如 foo 存在于原型链上层,赋值语句 myObject.foo = “bar” 的行动就会有些差别。

假如属性名 foo 既涌现在 myObject 中也涌现在 myObject 的 [[Prototype]] 链上层,那末就会发作屏障。myObject 中包括的 foo 属性会屏障原型链上层的一切 foo 属性,由于myObject.foo 总是会挑选原型链中最底层的 foo 属性。

假如 foo 不直接存在于 myObject 中而是存在于原型链上层时 myObject.foo = “bar” 会涌现的三种状况。

假如在[[Prototype]]链上层存在名为foo的一般数据接见属性(拜见第3章)而且没有被标记为只读(writable:false),那就会直接在 myObject 中增加一个名为 foo 的新属性,它是屏障属性。

假如在[[Prototype]]链上层存在foo,然则它被标记为只读(writable:false),那末没法修正已有属性或许在 myObject 上建立屏障属性。假如运行在严厉形式下,代码会抛出一个毛病。不然,这条赋值语句会被疏忽。总之,不会发作屏障。

假如在[[Prototype]]链上层存在foo而且它是一个setter(拜见第3章),那就一定会挪用这个 setter。foo 不会被增加到(或许说屏障于)myObject,也不会从新定义 foo 这个 setter。

大多数开发者都以为假如向 [[Prototype]] 链上层已存在的属性([[Put]])赋值,就一定会触发屏障,然则如你所见,三种状况中只要一种(第一种)是如许的。假如你愿望在第二种和第三种状况下也屏障 foo,那就不能运用 = 操纵符来赋值,而是运用 Object.defineProperty(..)来向 myObject 增加 foo。

2 “类”

组织函数+原型函数,两个函数经由过程 constructor 属性和 prototype 属性相关联。

类关联

function Foo() {}
let foo = new Foo();

1 foo instanceof Foo

instanceof 操纵符的左操纵数是一个一般的对象,右操纵数是一个函数。instanceof 回复的问题是:在 a 的整条 [[Prototype]] 链中是不是有指向 Foo.prototype 的对象

2 Foo.prototype.isPrototypeOf( foo )

isPrototypeOf(..) 回复的问题是:在 foo 的整条 [[Prototype]] 链中是不是涌现过 Foo.prototype 。我们也能够直接猎取一个对象的 [[Prototype]] 链。Object.getPrototypeOf(foo); 如Object.getPrototypeOf( foo ) === Foo.prototype; // true 或许 a.__proto__ === Foo.prototype; // true
《笔记-你不知道的JS-原型》

    原文作者:小利子
    原文地址: https://segmentfault.com/a/1190000019376790
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞