前端面试题总结二(js原型继承)

综合技术 2018-05-18 阅读原文

今天这篇文章整理了JS原型和继承的一些知识点,面试的时候 基!本!都!会!问!还不快认真阅读下文,看看你还有哪些知识点需要掌握吧~

1.原型链

基本思想:利用原型让一个引用类型继承另外一个引用类型的属性和方法。

构造函数,原型,实例之间的关系:每个构造函数都有一个原型对象,原型对象包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

原型链实现继承例子:

function
a() {

this
.name =
'张三'
;

}

a.prototype.getName =
function
() {

return
this
.name;

}

function
b() {

this
.name =
'李四'
;

}

//继承了a

b.prototype =
new
a();

b.prototype.getName =
function
(){

return
this
.name;

}

var
instance =
new
b ();

console.log(instance.getName());
//'李四'

改简单点

function a() {

this.name = '张三';

}

a.prototype.getName = function() {

return this.name;

}

var instance = new a();

console.log(instance.getName());//'张三'

2.借用构造函数

基本思想:在子类型构造函数的内部调用超类构造函数,通过使用call()和apply()方法可以在新创建的对象上执行构造函数。

例子:

function
a() {

this
.colors = [
"red"
,
"blue"
,
"green"
];

}

function
b() {

a.call(
this
);
//继承了a

}

var
instance1 =
new
b();

instance1.colors.push(
"black"
);

console.log(instance1.colors);
//"red","blue","green","black"

var
instance2 =
new
b();

console.log(instance2.colors);
//"red","blue","green"

3.组合继承

基本思想:将原型链和借用构造函数的技术组合在一块,从而发挥两者之长的一种继承模式。

function a(name) {

this.name = name;

this.colors = ["red","blue","green"];

}

a.prototype.sayName = function() {

console.log(this.name);

}

function b(name, age) {

a.call(this,name);//继承属性

this.age = age;

}

//继承方法

b.prototype = new a();

b.prototype.constructor = b;//这个是为了让b的 构造函数
重新指回这个类本身,否则的话它会变成之前继承的那个类的 构造函数
, 在后面再调用的时候可能会出现意想不到的情况

b.prototype.sayAge = function() {

console.log(this.age);

}

var instance1 = new b("Hong",18);

instance1.colors.push("black");

console.log(instance1.colors);//"red","blue","green","black"

instance1.sayName();//"Hong"

instance1.sayAge();//18

var instance2 = new b("su",20);

console.log(instance2.colors);//"red","blue","green"

instance2.sayName();//"su"

instance2.sayAge();//20

3.寄生组合继承

function
beget(obj){
// 生孩子函数 beget:龙beget龙,凤beget凤。


var
F =
function
(){};


F.prototype = obj;


return
new
F();

}

function
Super(){


// 只在此处声明基本属性和引用属性


this
.val = 1;


this
.arr = [1];

}

// 在此处声明函数

Super.prototype.fun1 =
function
(){};

Super.prototype.fun2 =
function
(){};

//Super.prototype.fun3...

function
Sub(){


Super.call(
this
);
// 核心


// ...

}

var
proto = beget(Super.prototype);
// 核心

proto.constructor = Sub;
// 核心

Sub.prototype = proto;
// 核心

var
sub =
new
Sub();

alert(sub.val);

alert(sub.arr);

这个方式是最佳方式,但是太麻烦,一般只是课本上用,不多解释

4寄生式继承

function
beget(obj){
// 生孩子函数 beget:龙beget龙,凤beget凤。


var
F =
function
(){};


F.prototype = obj;


return
new
F();

}

function
Super(){


this
.val = 1;


this
.arr = [1];

}

function
getSubObject(obj){


// 创建新对象


var
clone = beget(obj);
// 核心


// 增强


clone.attr1 = 1;


clone.attr2 = 2;


//clone.attr3...


return
clone;

}

var
sub = getSubObject(
new
Super());

alert(sub.val);
// 1

alert(sub.arr);
// 1

alert(sub.attr1);
// 1



想了解ES6中的继承请关注下一篇文章

博客园-原创精华区

责编内容by:博客园-原创精华区阅读原文】。感谢您的支持!

您可能感兴趣的

遨游GMTC大前端大会 在众多工程化分享中,我觉得来自51信用卡的前端架构组负责人的分享比较清晰、实用和可操作。他讲了他到51信用卡后,建立了一套从开发到发布的整个工程化体系方案。从开...
WebAssembly:解决 JavaScript 痼疾的一颗银弹?... 《没有银色子弹》是 Fred Brooks 在 1987 年所发表的一篇关于软件工程的经典论文。该论文的主要论点是,没有任...
深入浅出:JavaScript作用域链 1. 什么是作用域 任何程序设计语言都有作用域的概念,简单的说,作用域就是变量的作用范围。 2. 变量的分类和变量作用域的分类 在JavaSc...
区分defer和async 今天要介绍的让脚本延迟加载,让脚本延迟加载的方式有多种,最简单粗暴的方法就是将 标签放在 标签的最下面,这样就可以按照先后顺序依次执行...