泉源:
个人博客
白话诠释 Javascript 原型继承(prototype inheritance)
什么是继承?
学过“面向对象”的同学们是不是还记得,先生成天挂在嘴边的面向对象三大特性:封装,继承,多态。本日我们就来白话一下javascript中的原型继承,没学过的同学们也不必忧郁,随着往下走,我相信你会邃晓的。
继承,固然是面向对象个中的一种头脑和概念了,所谓继承,望文生义就是继承了。。。
比方说小明是老明唯一的儿子,老明有一个亿的资产,这一个亿的资产虽然不在小明手里,然则小明是老明儿子,小明在肯定程度上“继承”了他老爸给他供应的这么多的资产,小明不仅可以享用自身赚来的钱,也可以随时消耗他父辈的资产。
在顺序中,实在也是相似的,假如一个对象A继承了对象B,那末对象A不仅可以运用自身的属性和要领,同时也可以运用父级B中的属性和要领。
为了可以说邃晓Javascript 中的原型继承,就不得不说javascript中的对象。
javascript对象两种建立(声明)体式格局
在javascript中你可以运用以下体式格局建立一个javascript 对象(object).
- 对象字面量(object literal)体式格局
- 组织函数(constructor)体式格局 // es6中可以用class建立一个真正的对象
- Object.create(prototype) //经常使用此要领举行对象间继承
第一种对象字面量体式格局很简单粗犷:
var a = {}; // 我建立了一个空对象a
第二种“组织函数”体式格局来“建立对象”。
“组织函数”只是建立一个对象的第一步!有了组织函数以后,第二部就是用它建立一个对象!
所以, 第一步,来一个组织函数,你可以把它当做一个一般函数,比方:
function People(name) {
this.name = name;
}
这个函数也可以接收参数,假如人人对this关键字不相识,请先看《详解javascript this关键字》这个教程,这里我就不烦琐了。
我们有了组织函数以后,第二步最先运用它组织一个函数。
在javascript中,我们运用 “new” 操作符 + 组织函数 来建立一个对象。
var a = new People('xiaoming');
var b = new People;
趁便提一下,假如你不想给组织函数传入参数,那末带不带括号都是一样的,也就是说:
var a = new People;
var b = new People();
这两种建立对象体式格局都准确。
小提示:实在第一种对象字面量体式格局只是构建对象的语法糖(syntax sugar),底层照样运用组织函数体式格局组织的:
new Object()
人人不相信的话,可以翻开你的chrome的控制台,直接输入:
Object
是不是是看到了下面这一行?
function Object() { [native code] }
这个Object也是个组织函数,只不过这里原生代码。
原型prototype
如今人人晓得了javascript中对象建立的两种体式格局。
var a = {};
var xiaoming = new People();
接下来这句话请人人反复三遍:
一切的javascript对象都从一个叫“原型”的处所继承了一切的属性和要领!
这个“原型”是个啥?就是个对象!你可以把它设想成:{}。
我们前面说了建立对象的两种要领:
1, 对象字面量
var a = {};
// 实在即是
var a = new Object;
2, 组织函数
function People(){
}
var a = new People();
我们说过了:
一切的javascript对象都从一个叫“原型”的处所继承了一切的属性和要领!
上面这两个例子中对象是:
a
那末原型(prototype)在哪呢?人人试着和我一样做一下:
console.log(Object.prototype);
console.log(People.prototype);
是不是是都输出了一个对象?
我们之前也说了,原型(prototype)就是一个对象罢了,如今人人也晓得它在哪了吧?原型就是组织函数的一个属性,这里能够听着有点别扭,函数的属性?对,javascript中的组织函数也是对象!
主要的事变说三遍:javascript的原型(prototype)是什么?就是“组织函数”下的一个对象叫做“原型”(prototype)
再添一句,这个原型对象中又有个名为“constructor”的属性,指向了该函数自身。
function People(){}
People.prototype.constructor === People // true
再提示一下,原型只存在在“组织函数”中,有些同学会误会的去找一个“对象”或“对象字面量”的原型(prototype),由于我们说了原型(prototype)只存在在“组织函数”中,所以去对象或对象字面量里找原型的找不到的,只能返回undefined。比方:
var a = {};
console.log(a.prototype) // 返回undefined
// 或许
function People() {}
var p = new People;
console.log(p.prototype) // 依旧返回undefined
// 然则
console.log(People.prototype) // 就返回一个{} 固然这里面有很多原生的要领
然则,另有一个迥殊属性
__proto__
可以让你“向父级”检察,当前对象继承的“原型”是谁?就是孩子找爸爸。
翻开你的chrome浏览器的控制台,接着上面的代码继承实验:
a.__proto__ // Object {}
p.__proto__ // Object {}
a.__proto__ === Object.prototype // true
p.__proto__ === People.prototype // true
// 我们发明两个对象的原型都是对象。
// 那末我们再来看看组织函数“继承”的原型是谁?
Object.__proto__ // function () {}
People.__proto__ // function () {}
看到这里,愿望你能邃晓,不管是javascript自带的,照样我们自定义的组织函数依旧继承自匿名函数的原型!(愿望你没晕)
原型继承
有了上面的铺垫,我们终究可以最先说一下原型继承了。假如你上面的知识点都明白了,明白原型继承不在话下。
来个例子:
function People(name) {
this.name = name;
}
People.prototype.sayHi = function () {
console.log('hi, my name is ', this.name);
};
var a = new People('xiaoming');
a.sayHi(); // hi, my name is xiaoming
var b = new People('laoming');
b.sayHi(); // hi, my name is laoming
这类体式格局很简单也很直接,你在组织函数的原型上定义sayHi要领,那末用该组织函数实例化出来的对象都可以经由过程原型继承链访问到定义在组织函数原型上的要领。
明白了上述内容,你可以直接应用javascript的原型继承,也可以用它为基本组织自身“类”觉得小库。