JavaScript 的原型链
来源:互联网 发布:hip2p 网络摄像机 编辑:程序博客网 时间:2024/05/05 21:29
假设 Foo / Bar 是构造函数:
function Foo(name) { this.name = name}function Bar() { this.setAge = (age) => this.age = age this.showAge = () => console.log(this.age)}let foo = new Foo('foo')
总结一下,就是:
__proto__
属性属于对象,prototpye
属性属于构造函数。因此上例中,对象 foo 具有
__proto__
属性,但没有prototype
属性。Foo 和 Bar 具有prototype
属性。foo.__proto__ // 有值 foo.prototype // undefined Foo.prototype // 有值 Foo.__proto__ // ?? 有值还是 undefined,留个悬念
对象的
__proto__
指向其构造函数的prototype
。foo.__proto__ === Foo.prototype // true
__proto__
总是指向prototype
,而prototype
总是被__proto__
所指向。prototype
也是对象,因此它也有自己的__proto__
属性。根据上面所言,__proto__
指向对象自身构造函数的prototype
属性,而这里的Foo.prototype
的构造函数是谁呢?因为Foo.protype
是一个普通对象,Object,它是通过new Object()
创造出来的,所以它的构造函数是 Object,所以它指向Object.protype
。Foo.prototype.__proto__ === Object.prototype // true
又因为
foo.__proto__ = Foo.prototype
,所以,可得foo.__proto__.__proto__ === Object.prototpye // true
Object.prototype
也是对象,那么它的__proto__
又是多少呢,规定Object.prototype.__proto__ = null
(呃,有点特殊),因此foo.__proto__.__proto__.__proto__ === null // true
一般来说,一个普通的自定义的构造函数生成的对象,通过向上查找三级
__proto__
就能得到 null 值。如上所示,因为对象是通过
__proto__
这条链条向上查找方法和变量,而__proto__
指向的是各级构造函数的prototype
属性。因此,为构造函数添加原型方法时,这些方法必须绑定在prototype
属性上,这样才能被对象的__proto__
所查找到。function Foo(name) { this.name = name } let foo = new Foo('foo') Foo.prototype.showName = function() { console.log(this.name) } foo.showName() // 'foo'
上面说到,一般来说,一个普通的自定义的构造函数生成的对象,向上查找三级
__proto__
就得到了 null,它们的链条只有三级。如果我们想实现继承关系,比如让 Foo 继承自 Bar,让 foo 能用上 Bar 中的方法,那要怎么办呢。方法就是手动修改这条默认的__proto__
链条。我们要让Foo.prototype.__proto__
不再指向默认的Object.prototype
,而是指向Bar.prototype
。Foo.prototype.__proto__ = Bar.prototype
那么就可以得到:
foo.__proto__.__proto__ = Bar.prototype
这样,foo 就可以用上 Bar 中的方法了:
foo.setAge(18) foo.showAge()
呃呃,但是实验之后,证明我还是太天真了,上面通过强行改变
prototype.__proto__
的方法并不管用,原因我想可能是因为__proto__
这个值是一个内部值,并不是一个公开的值,从它的前缀是 2 个下划线可知,因此它可以被外部所读取,但不能被外部所修改,只能在内部被修改。为了达到相同的效果,该怎么做呢。前面我们得知:foo = new Foo('foo') // 得到 foo.__proto__ --> Foo.prototype
那么:
Foo.prototype = new Bar() // 得到 Foo.protype.__proto__ --> Bar.prototype Foo.protoype.__proto__ === Bar.prototype // true
现在我们知道了,
prototype
也有一个__proto__
属性,那它还包含什么值呢?我们在 chrome dev tool 中打印一下它。function Foo(name) { this.name = name } Foo.prototype.showName = function() { console.log(this.name) } > Foo.prototype < Object {showName: function, constructor: function} showName: function () constructor: function Foo(name) __proto__: Object
除了我们已知的
__proto__
和后来附加的原型方法showName
,还有一个属性,叫constructor
,从名字上看,它应该是表示构造函数,而它的值正是构造函数function Foo(name){...}
。所以得到:Foo.prototype.constructor === Foo // true
- Javascript的原型链
- Javascript 的原型链
- JavaScript 的原型链
- JavaScript的原型链
- 浅谈javascript的原型及原型链
- JavaScript的原型和原型链
- javascript的原型与原型链
- JavaScript的原型与原型链
- JavaScript的原型与原型链
- JavaScript原型、原型链、对象的创建
- javascript的原型与原型链
- JavaScript原型,原型链
- JavaScript-原型、原型链
- JavaScript原型,原型链
- JavaScript-原型、原型链
- 浅析JavaScript的原型链
- javascript的原型链基础知识
- javascript原型链的形成
- 关于敏捷开发的一点总结与感悟
- MFC中的CApp,CMainFrame,CDoc,CView
- LRC歌词解析
- More Python
- Spring:SAXParseException
- JavaScript 的原型链
- lintcode--最长单词
- 链表
- Light---一个物体阴影的影响要素
- null
- POJ2106 Boolean Expressions / Openjudge Boolean Expressions (递归)全局题号1108
- C++连接CTP接口实现简单量化交易(行情、交易、k线、策略)
- JSON.stringify()技巧
- [kuangbin带你飞]专题二 搜索进阶 G