本文源自 @NoteCode 引用的 Vjeux 文章 Javascript – How Prototypal Inheritance really works,阐述了 原型编程 的工作原理,这里记录一下理解要点。
下面这个代码片段说明了 JS 引擎是如何获取一个属性的:
function getProperty(obj, prop) {
if (obj.hasOwnProperty(prop))
return obj[prop]
else if (obj.__proto__ !== null)
return getProperty(obj.__proto__, prop)
else
return undefined
}
原型继承的写法
var Point = {
x: 0,
y: 0,
print: function () { console.log(this.x, this.y); }
};
var p = {x: 10, y: 20, __proto__: Point};
p.print(); // 10 20
大部分教科书的写法
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
print: function () { console.log(this.x, this.y); }
};
var p = new Point(10, 20);
p.print(); // 10 20
这是什么鬼东西嘛!和原型继承完全不同! Point 成了函数,prototype 成了 Point 的一个属性!
new 运算符做了些什么?
原来 Brendan_Eich 在实现 JS 时,为了效仿 JAVA,写了 new 运算符。
new 运算符 函数 F 和其参数 arguments:new F(arguments...),三步:
1. 创建类实例
这里的类就是 function F,创建了一个空对象,其属性 __proto__ 赋值为 F.prototype。
要注意破除思维定式,在语义上,我们把具有类含义的 function 名字的首字母大写;
2. 初始化这个实例
调用 function F,传参 arguments,this
指向这个实例;
3. 返回这个实例;
prototype 就是 '基类'
每个对象都有一个 prototype,每个 prototype 也是一个对象。每个对象是通过自己的 prototype 来继承属性和方法的;
constructor @ ES6
constructor 是一个函数对象,用于创建和初始化对象;
constructor 的 prototype 属性是一个 prototype 对象,可以用来实现继承和共享属性;
prototype @ ES6
prototype 是一个对象,提供了供其他对象使用的共享属性;
当 constructor 创建对象时,该对象隐性指向 constructor 的属性 prototype,目的是为了解决属性指向问题;可以使用 constructor.prototype 引用该属性;
prototype 里面的属性是共享的;所有对象通过继承共享了该 prototype;一个对象也可以通过 Object.create 这个内置函数来创建。
我的理解是用prototype指定的属性方法其实就是java对象的static修饰下的属性方法,不过作为脚本语言,这样的设计也是非常合理的。
特点就是共享的,只有一份;
只有对象,没有 '类';
通常一个对象 O 如果要作为被继承对象,只会设计该对象 O 的构造函数和设计该对象 O 的属性 prototype,而通常不会再设计该对象 O 的其他属性;
prototype-chain 链就是指针;
prototype 是一种隐式引用组合(因引用而共享);
o.prototype.ps1 = "property-shared-1"; 这叫修改所有对象ps1的值
o2.ps1 = "x"; 这叫覆盖;
constructor | prototype | 备注 |
---|---|---|
CF(arguments...){...} | CF.prototype={...} | |
CF.p1 p1 是一个属性 | p1 属 CF 私有 | |
contructor 中出现的属性 | 可继承的属性,new 对象中可访问; |
contructor function
contructor property
prototype function
prototype property
关于 Vjeux
Vjeux 是 Facebook React Native 项目的一个前端开发软件工程师。
延伸
JavaScript-Garden
A growing collection of documentation about the most quirky parts of the JavaScript programming language.