(翻译) Inheritance and the prototype chain 继承和原型链
JavaScript is a bit confusing for developers experienced in class-based languages (like Java or C++), as it is dynamic and does not provide a class
implementation per se (the class
keyword is introduced in ES2015, but is syntactical sugar, JavaScript remains prototype-based).
When it comes to inheritance, JavaScript only has one construct: objects. Each object has a private property which holds a link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null
as its prototype. By definition, null
has no prototype, and acts as the final link in this prototype chain.
Nearly all objects in JavaScript are instances of Object
which sits on the top of a prototype chain.
While this confusion is often considered to be one of JavaScript's weaknesses, the prototypal inheritance model itself is, in fact, more powerful than the classic model. It is, for example, fairly trivial to build a classic model on top of a prototypal model.
JavaScript对于那些经历过以类为基础的语言(Java或者C++)的人可能有一点迷惑,它是动态的并且不提供类的实现(ES2015中类的实现是一个基于prototype的语法糖)
讨论继承的时候,JavaScript只有一个结构,object(对象),每个对象都有一个私有属性,这个属性指向另一个对象, 称为 它的 Prototype,那个prototype对象也有自己的prototype,如此如此,直到一个对象最终到达null为它的原型,通过定义,null没有原型,并且被认为是这个原型链中的最后一层link。
几乎所有的javascript中的object都是继承自Object,Object位于原型链的顶端。
这个迷惑的地方经常被认为是Javascript语言的一大弱点,基于原型的继承模型,事实上,这个模型比经典模型更加Powerful,是的,完全可以基于原型模型来建立经典模型。
——————————————————————————————————————————————————————————————————
Inheritance with the prototype chain
Inheriting properties
JavaScript objects are dynamic "bags" of properties (referred to as own properties). JavaScript objects have a link to a prototype object. When trying to access a property of an object, the property will not only be sought on the object but on the prototype of the object, the prototype of the prototype, and so on until either a property with a matching name is found or the end of the prototype chain is reached.
Following the ECMAScript standard, the notation someObject.[[Prototype]]
is used to designate the prototype of someObject
. Since ECMAScript 2015, the [[Prototype]]
is accessed using the accessors Object.getPrototypeOf()
and Object.setPrototypeOf()
. This is equivalent to the JavaScript property __proto__
which is non-standard but de-facto implemented by many browsers.
It should not be confused with the func.prototype
property of functions, which instead specifies the [[Prototype]]
to be assigned to all instances of objects created by the given function when used as a constructor. The Object.prototype
property represents the Object
prototype object.
Here is what happens when trying to access a property:
JS中万物皆对象。
通过原型链继承
继承属性
javascript的object是属性的动态'bag',javascript object有通向prototype object 的链接,当尝试访问一个object的属性时,这个属性不光会被在object上寻找,还会这个object的原型上查找,原型的原型,直到原型链的末端,直到找到这个属性的名字。
通过ECMAScript标准,someObject.[[Prototype]]用来指定某个someObject 的原型,从ES2015规范(ES6实现)开始,[[Prototype]]通过Object.getPrototypeOf()和Object.setPrototypeOf()来访问,这等价于JavaScript的__proto__属性,这个属性是不标准的,但事实上被很多浏览器实现了。
函数的func.prototype 等价于 它实例出来的对象的__proto__属性
when you call
var o = new Foo();
JavaScript actually just does
var o = new Object();
o.[[Prototype]] = Foo.prototype;
Foo.call(o)
function 士兵(ID){
var 临时对象 = {}
临时对象.__proto__ = 士兵.原型
临时对象.ID = ID
临时对象.生命值 = 42
return 临时对象
}
士兵.原型 = {
兵种:"美国大兵",
攻击力:5,
行走:function(){ /*走俩步的代码*/},
奔跑:function(){ /*狂奔的代码*/ },
死亡:function(){ /*Go die*/ },
攻击:function(){ /*糊他熊脸*/ },
防御:function(){ /*护脸*/ }
}
// 保存为文件:士兵.js
然后就可以愉快地引用「士兵」来创建士兵了:
var 士兵们 = []
for(var i=0; i<100; i++){
士兵们.push(士兵(i))
}
兵营.批量制造(士兵们)
JS 之父的关怀
JS 之父创建了 new 关键字,可以让我们少写几行代码:
只要你在士兵前面使用 new 关键字,那么可以少做四件事情:
- 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
- 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
- 不用 return 临时对象,因为 new 会帮你做;
- 不要给原型想名字了,因为 new 指定名字为 prototype。
这一次我们用 new 来写
function 士兵(ID){
this.ID = ID
this.生命值 = 42
}
士兵.prototype = {
兵种:"美国大兵",
攻击力:5,
行走:function(){ /*走俩步的代码*/},
奔跑:function(){ /*狂奔的代码*/ },
死亡:function(){ /*Go die*/ },
攻击:function(){ /*糊他熊脸*/ },
防御:function(){ /*护脸*/ }
}
// 保存为文件:士兵.js
然后是创建士兵(加了一个 new 关键字):
var 士兵们 = []
for(var i=0; i<100; i++){
士兵们.push(new 士兵(i))
}
兵营.批量制造(士兵们)
new 的作用,就是省那么几行代码。(也就是所谓的语法糖)
注意 constructor 属性
new 操作为了记录「临时对象是由哪个函数创建的」,所以预先给「士兵.prototype」加了一个 constructor 属性:
士兵.prototype = {
constructor: 士兵
}
如果你重新对「士兵.prototype」赋值,那么这个 constructor 属性就没了,所以你应该这么写:
士兵.prototype.兵种 = "美国大兵"
士兵.prototype.攻击力 = 5
士兵.prototype.行走 = function(){ /*走俩步的代码*/}
士兵.prototype.奔跑 = function(){ /*狂奔的代码*/ }
士兵.prototype.死亡 = function(){ /*Go die*/ }
士兵.prototype.攻击 = function(){ /*糊他熊脸*/ }
士兵.prototype.防御 = function(){ /*护脸*/ }
或者你也可以自己给 constructor 重新赋值:
士兵.prototype = {
constructor: 士兵,
兵种:"美国大兵",
攻击力:5,
行走:function(){ /*走俩步的代码*/},
奔跑:function(){ /*狂奔的代码*/ },
死亡:function(){ /*Go die*/ },
攻击:function(){ /*糊他熊脸*/ },
防御:function(){ /*护脸*/ }
}
完。
function 士兵(ID){
var 临时对象 = {}
临时对象.__proto__ = 士兵.原型
临时对象.ID = ID
临时对象.生命值 = 42
return 临时对象
}
士兵.原型 = {
兵种:"美国大兵",
攻击力:5,
行走:function(){ /*走俩步的代码*/},
奔跑:function(){ /*狂奔的代码*/ },
死亡:function(){ /*Go die*/ },
攻击:function(){ /*糊他熊脸*/ },
防御:function(){ /*护脸*/ }
}
// 保存为文件:士兵.js
然后就可以愉快地引用「士兵」来创建士兵了:
var 士兵们 = []
for(var i=0; i<100; i++){
士兵们.push(士兵(i))
}
兵营.批量制造(士兵们)
JS 之父的关怀
JS 之父创建了 new 关键字,可以让我们少写几行代码:
只要你在士兵前面使用 new 关键字,那么可以少做四件事情:
- 不用创建临时对象,因为 new 会帮你做(你使用「this」就可以访问到临时对象);
- 不用绑定原型,因为 new 会帮你做(new 为了知道原型在哪,所以指定原型的名字为 prototype);
- 不用 return 临时对象,因为 new 会帮你做;
- 不要给原型想名字了,因为 new 指定名字为 prototype。
这一次我们用 new 来写
function 士兵(ID){
this.ID = ID
this.生命值 = 42
}
士兵.prototype = {
兵种:"美国大兵",
攻击力:5,
行走:function(){ /*走俩步的代码*/},
奔跑:function(){ /*狂奔的代码*/ },
死亡:function(){ /*Go die*/ },
攻击:function(){ /*糊他熊脸*/ },
防御:function(){ /*护脸*/ }
}
// 保存为文件:士兵.js
然后是创建士兵(加了一个 new 关键字):
var 士兵们 = []
for(var i=0; i<100; i++){
士兵们.push(new 士兵(i))
}
兵营.批量制造(士兵们)
new 的作用,就是省那么几行代码。(也就是所谓的语法糖)
(翻译) Inheritance and the prototype chain 继承和原型链的更多相关文章
- Inheritance and the prototype chain 继承和 原型 链
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain Inherita ...
- JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- JavaScript继承与原型链
对于那些熟悉基于类的面向对象语言(Java 或者 C++)的开发者来说,JavaScript 的语法是比较怪异的,这是由于 JavaScript 是一门动态语言,而且它没有类的概念( ES6 新增了c ...
- 一篇JavaScript技术栈带你了解继承和原型链
作者 | Jeskson 来源 | 达达前端小酒馆 1 在学习JavaScript中,我们知道它是一种灵活的语言,具有面向对象,函数式风格的编程模式,面向对象具有两点要记住,三大特性,六大原则. 那么 ...
- JavaScript之继承(原型链)
JavaScript之继承(原型链) 我们知道继承是oo语言中不可缺少的一部分,对于JavaScript也是如此.一般的继承有两种方式:其一,接口继承,只继承方法的签名:其二,实现继承,继承实际的方法 ...
- JavaScript中的继承与原型链
先看一个例子 function User(){} var u1 = new User(); console.log(u1.prototype);// undefined 使用对象实例无法访问到prot ...
- JavaScript -- 继承与原型链
JavaScript对象有一个指向一个原型对象的链,当试图访问一个对象的属性的时候,他不仅仅会在该对象上面搜寻,还会搜寻该对象的原型,以及对象的原型的原型,依次层层搜索,直到找到名字匹配的属性或者到达 ...
- 关于JavaScript的原型继承与原型链
在讨论原型继承之前,先回顾一下关于创建自定义类型的方式,这里推荐将构造函数和原型模式组合使用,通过构造函数来定义实例自己的属性,再通过原型来定义公共的方法和属性. 这样一来,每个实例都有自己的实例属性 ...
- 为什么Object.prototype在Function的原型链上与Function.prototype在Object的原型链上都为true
关于javascript的原型链有一个问题我一直很疑惑:为什么 Function instanceof Object 与 Object instanceof Function都为true呢? Func ...
随机推荐
- ios风格的时间选择插件
1.起因 在上个项目中,客户希望时间选择插件可以是ios风格的那种,但是找了很久,发现并没有用vue的ios风格时间插件,于是自己便自己造了一个轮子. 2.插件效果 3.插件依赖以及安装使用 插件依赖 ...
- C#通过SendMessage发送消息,改变其他程序的下拉框控件(ComboBox)的值
IntPtr cbh= new IntPtr(handle); //ComboBox的句柄 SendMessage(cbh, 0x014D, new IntPtr(-1), "需要选中的下拉 ...
- django-5-自定义模板过滤器及标签
<<<代码布局(自定义的代码放哪里)>>> (1)某个app特有的 1.一般放app目录下 固定名为templatetags 的python文件夹里鸭,如果是别的 ...
- 【codeforces 723E】One-Way Reform
[题目链接]:http://codeforces.com/contest/723/problem/E [题意] 给你一个无向图; 让你把这m条边改成有向图; 然后使得出度数目等于入度数目的点的数目最多 ...
- 教你十分钟构建好 SpringBoot + SSM 框架
目前最主流的 java web 框架应该是 SSM,而 SSM 框架由于更轻便与灵活目前受到了许多人的青睐.而 SpringBoot 的轻量化,简化项目配置, 没有 XML 配置要求等优点现在也得到了 ...
- windows无法开机解决方法
电脑启动弹出错误Ntldr is missing , 解决方法:重新从xp中拷贝一个出来粘贴上就行 电脑启动弹出错误Ntldr is compressed ,表示分区中的文件被压缩了 解决方法:首先把 ...
- NEFU 117
可以用素数定理来解决. 素数定理:小于n的素数个数记为p(n),则随着n的增长,p(n)/(n/ln(n))=1. #include <iostream> #include <mat ...
- java 微信server录音下载到自己server
/** * @author why * */ public class VoiceDownload { /** * * 依据文件id下载文件 * * * * @param mediaId * * 媒体 ...
- ym—— Android网络框架Volley(终极篇)
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103).谢谢支持! 没看使用过Volley的同学能够,先看看Android网络框架Volley(体验篇)和 ...
- 2015.04.30,外语,读书笔记-《Word Power Made Easy》 14 “如何谈论日常现象” SESSION 40
1. money, and what it will buy penury(['penjuri] n. 贫穷,拮据),来自拉丁词语penuria(need,needness的意思),主要指缺乏财富资源 ...