关于前端:温故而知新-重新认识JavaScript的原型

57次阅读

共计 1936 个字符,预计需要花费 5 分钟才能阅读完成。

温故而知新 – 重新认识 JavaScript 的原型

什么是prototype

实现面向对象的一个重要机制。

JavaScript中对象有一个非凡的 [[Prototype]] 内置属性,其实就是对于其余对象的援用。简直所有的对象在创立时 [[Prototype]] 属性都会被赋予一个非空的值,能够通过 __proto__ 拜访该属性。此外,prototypeJavaScript 中函数的一个属性。

所有一般的 [[Prototype]] 链最终都会指向内置的Object.prototype

为什么须要prototype

记住:JavaScrip没有类来作为对象的形象模式。JavaScript中只有对象

反向思考,如果没有 prototype 会怎么?

var obj = {}
obj.toString()

没有 prototype,那toString 就是 undefined 的,毕竟 obj 是个空对象。

总结来看,原型及其相干,最大的作用是 复用能力,带来的益处最直观的就是节俭内存空间:不再须要每个对象都从新定义一个雷同逻辑性能或意义的属性。

关注点

1. 属性设置与屏蔽

myObject.foo = "bar";

myObject 对象中蕴含名为 foo 的一般数据拜访属性,这条赋值语句只会批改已有的属性值。

foo 不是 myObject 本身的属性,[[Prototype]]链就会被遍历,相似 [[Get]] 操作。原型链上找不到 foo,则foo 会被间接增加到 myObject 上。

但,foo若存在于原型链上,赋值语句 myObject.foo = "bar" 的行为存在差别:

  1. 假使在 [[Prototype]] 链上存在 foo 属性,同时不是只读 (writable: false),则会间接myObject 中增加一个名为 foo 的新属性,它是 屏蔽属性
  2. 若在 [[Prototype]] 链上存在 foo,然而为只读(writable: false),则无奈批改已有属性或者在myObject 上创立屏蔽属性。在严格模式下,代码会抛出一个谬误。否则,赋值语句会被疏忽。总之,不会产生屏蔽。须要留神的是,这个限度只存在于 = 赋值中,应用 Object.defineProperty(...) 并不会受影响

来看代码,测试执行下:

class Parent {}
class Son extends Parent {}

Object.defineProperty(Parent, 'foo', {writable: false, value: 'bar'});

Son.foo; // 输入 "bar"
Son.foo = "foo";
Son.foo; // 仍旧输入 "bar", 上一条赋值语句被忽略了
// 然而能够应用 Object.defineProperty(...)
Object.defineProperty(Son, 'foo', {value: 'son_bar'});
Son.foo; // 输入 "son_bar"
Parent.foo; // 输入 "bar"

2. 对于class

function Foo() {}

var a = new Foo();

Object.getPrototypeOf(a) === Foo.prototype; // true

调用 new Foo() 时会创立 a,其中一步就是将a 外部的 [[Prototype]] 链接到 Foo.prototype 所指向的对象。

须要关注:

1.在 JavaScript 中,不能创立一个类的多个实例,只能创立多个对象 ,它们[[Prototype]] 关联的是同一个对象。
2.并没有初始化一个类,实际上并没有从 ’ 类 ’ 中复制任何行为到一个对象中,只是让两个对象相互关联

3. 继承的实质

因为 JavaScrip 没有类来作为对象的形象模式,JavaScript中只有对象。继承的实质,能够了解为对象的关联

Object.create()

Object.create(null)会创立一个领有空 (或者说null)[[Prototype]] 链接的对象,这个对象无奈进行委托。因为这个对象没有原型链,所以 instanceof 操作符无奈进行判断,因而总是会返回 false。这些非凡的空 [[Prototype]] 对象通常被称作 ” 字典 ”,他们齐全不会受到原型链的烦扰,因而非常适合用来 存储数据

// Object.create()的 polyfill 代码
if (!Object.create) {Object.create = function(target) {function F() {}
        F.prototype = target;
        return new F();}
}

参考资料

  1. You Don’t Know JS: this & Object Prototypes
  2. 該來了解 JavaScript 的原型鍊了
  3. JavaScript 中 proto 和 prototype 存在的意义是什么

正文完
 0