原型链、继承 和 instanceof
参考:
MDN:instanceof
MDN:Inheritance and the prototype chain
理解JavaScript的原型链和继承
new实现了什么操作
new的过程发生了什么?
function A(name){
this.name = name
}
var a = new A('hehe')
// var a = new A('hehe') =>
var a = new Object();
a.__proto__ = A.prototype;
A.call(a, 'hehe');
原型链和prototype属性
原型链是什么
上面的 __proto__
是什么?
就是原型链,原型链是内部 [ [Prototype ]],指向它“父类”的prototype。
打开浏览器控制台,可以看到函数变量都有一个prototype属性(箭头函数没有)。
通过这一句a.__proto__ = A.prototype;
说明a的原型链就是指向函数A的prototype属性。
这里就有一个重要的认识了,虽然名字很像,但是原型链并不是prototype属性,同时原型链指向“父类”的prototype。几乎所有对象都有原型链(除了null和undefined),通过__proto__
可以看到原型链指向什么(当然最好使用 Object.getPrototypeOf 取原型链)
通过实验可以发现,js中对象的链可以非常复杂。
一图胜千言。这里借一张图。
简而言之
函数对象,Function,Object,Array等等的原型链都指向Function.prototype
通过new操作符创建的对象原型链指向原来的函数的prototype属性
Object.prototype属性的原型链指向null(到null就停止了)
而Function.prototype(Array,Date,String等等),以及函数对象的prototype,原型链都指向Object.prototype
prototype属性究竟是什么呢
可以看到是一个Object,有constructor和原型链。constructor是一个函数,也就是函数自身。这可以为后面提到的继承做准备。
instanceof什么意思
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
Syntax:
object instanceof constructor
意思就是object.__proto__===constructor.prototype
MDN的教程中举例
// defining constructors
function C() {}
var o = new C();
// true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof C;
但是
var simpleStr = 'This is a simple string';
var myString = new String();
simpleStr instanceof String; // returns false, checks the prototype chain, finds undefined
可是在浏览器中试验Object.getPrototypeOf(simpleStr) === String.prototype
结果是true,大概这算作一个特殊情况
如何实现继承
https://babeljs.io/repl/
可以在这个网站在线编译并查看结果
class A{
constructor(name) {
this.name= name
}
toString() {
return this.name
}
}
class B extends A {
toString(){
return this.name + 'b'
}
}
编译出来的ES5继承
function _inherits(subClass, superClass) {
subClass.prototype.__proto__=superClass.prototype;
}
var A = (function () {
function A(name) {
this.name = name;
}
A.prototype.toString = function toString() {
return this.name;
};
return A;
})();
var B = (function (_A) {
function B() {
if (_A != null) {
_A.apply(this, arguments);
}
}
_inherits(B, _A);
B.prototype.toString = function toString() {
return this.name + 'b';
};
return B;
})(A);
简单来说就是这样
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。