链接来源于
https://www.cnblogs.com/Grace-zyy/p/8206002.html
https://blog.csdn.net/u011504806/article/details/80676490
https://www.cnblogs.com/wangfupeng1988/tag/%E5%8E%9F%E5%9E%8B%E9%93%BE/
这明确一个定义:什么是继承?
继承就是通过某些方法来获取到父类的属性和方法
函数可以看作是一个对象,但是对象都是通过函数来创建的
如
var obj = { a: 10, b: 20 };
var arr = [5, 'x', true];
其实就是
//var obj = { a: 10, b: 20 };
//var arr = [5, 'x', true];
var obj = new Object();
obj.a = 10;
obj.b = 20;
var arr = new Array();
arr[0] = 5;
arr[1] = 'x';
arr[2] = true;
熟悉一下prototype,每一个函数都有一个属性叫做prototype
这个prototype的属性值是一个对象(属性的集合),默认只有一个constructor属性,指向这个函数本身。
如上图,SubType 是一个函数,右边方框就是它的原型
原型既然是一个对象(属性的集合),除了 constructor 外,还可以自定义许多属性,如:
当然也可以在自定义的方法的 prototype 中增加属性,如
function Fn() { }
Fn.prototype.name = '张三';
Fn.prototype.getAge = function () {
return 12;
};
再讲回 proto
“隐式原型”proto
再讲回 proto ,每个函数都有一个prototype,每个对象都有一个proto,可成为隐式原型
proto是个隐藏属性,指向创建该对象函数的prototype。
如:
function Fn(){ }
var f = new Fn()
f.__proto__ === Fn.prototype // true
但是,Object.prototype确实一个特例——它的proto指向的是null,切记切记!!!(因为Object.prototype是最顶层的了,一切都是对象,最顶层都是继承Object.prototype的属性内容的)
函数是一个对象,当然也有proto
function Foo(){ }
var a = new Object();
var fn = new Function();
Foo.__proto__ === Function.prototype // true
Foo.__proto__ === fn.__proto__ // true
Function.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
从上图可以看出:自定义函数 Foo.proto 指向 Function.prototype ,Object.proto 指向 Function.prototype。
但是,为什么有 Function.proto 指向 Function.prototype 呢?
其实原因很简单:Function 也是一个函数,函数是一种对象,也有proto属性。既然是函数,那么它一定是被 Function 创建。所以 Function 是被自身创建的。所以它的 proto 指向了自身的 Prototype
整个原型有关关系图如下:
instanceof操作符
判断对象是否是另外一个对象实例,也就是判断一对象是否在对象的原型链上能找到
function fn() { }
var f1 = new fn();
console.log(f1 instanceof fn); // true
console.log(f1 instanceof Object); //true
instanceof的判断规则为:
假设instanceof运算符的第一个变量是一个对象,暂时称为A;第二个变量一般是一个函数(也是对象),暂时称为B。
instanceof的判断规则是:沿着A的proto这条线来找,同时沿着B的prototype这条线来找,如果两条线能找到同一个引用,即同一个对象,那么就返回true。如果找到终点还未重合,则返回false。
说一下原型链
访问一个对象的属性时,先在基本属性中查找,如果没有,再沿着proto这条链向上找,这就是原型链。
在实际应用中如何区分一个属性到底是基本的还是从原型中找到的呢?
答案就是:hasOwnProperty这个函数,特别是在for…in…循环中,一定要注意。
(for...in循环会循环可枚举属性,自身属性和原型属性都会循环)
f1并没有hasOwnProperty这个方法,这个方法是从Object.prototype中来的。
由于所有的对象的原型链都会找到Object.prototype,因此所有的对象都会有Object.prototype的方法。这就是所谓的“继承”。
对象的原型链是沿着proto这条线走的,因此在查找f1.hasOwnProperty属性时,就会顺着原型链一直查找到Object.prototype。