3. js怎么实现继承?

  1. 使用原型prototype

  这个问题其实之前总结过了……但是面试时候有点忘……主要思想是记得的,但是不会写,还是基础太不牢靠,写的太少了。一开始因为不知道怎么能继承父类的方法属性,同时又不直接使用其原型,所以先写了一种,子类直接调用父类的原型。但是其中有些过程和方法肯定是写错了的……下面是正确的写法:

  

 1     var Parent = function(name){
2 this.name = name || "parent";
3 }
4 Parent.prototype.getName = function(){
5 return this.name;
6 }
7
8 var Child = function(name){
9 Parent.apply(this,arguments); //通过apply调用父类的构造函数来进行相同的初始化工作
10 }
11 Child.prototype = Parent.prototype;
12
13 var parent = new Parent("MyParent");
14 var child = new Child("MyChild");
15
16 console.log(parent.getName()); //MyParent
17 console.log(child.getName()); //MyChild //这样我们就只需要在子类构造函数中执行一次父类的构造函数,同时又可以继承父类原型中的属性,这也比较符合原型的初衷,就是把需要复用的内容放在原型中,我们也只是继承了原型中可复用的内容。

这里如果按序打印 parent, child, Parent, Child,则输出如下:

然后面试官又问如果只想改变子类的原型而不影响父类呢……我想了半天不知道怎么写,但是因为之前看过,就讲了下思想,就是用一个中间变量来存储其原型,然后给子类new一个……正确方法如下:

//临时构造函数模式(圣杯模式)(别问我为什么会有一个名字这么中二的方法我也不知道)
//上面借用构造函数模式最后改进的版本还是存在问题,它把父类的原型直接赋值给子类的原型,这就会造成一个问题,就是如果对子类的原型做了修改,那么这个修改同时也会影响到父类的原型,进而影响父类对象,这个肯定不是大家所希望看到的。为了解决这个问题就有了临时构造函数模式。
var Parent = function(name){
this.name = name || 'parent' ;
} ;
Parent.prototype.getName = function(){
return this.name ;
} ;
Parent.prototype.obj = {a : 1} ; var Child = function(name){
Parent.apply(this,arguments) ;//通过apply调用父类的构造函数来进行相同的初始化工作
} ;
var F = new Function();
F.prototype = Parent.prototype ;
Child.prototype = new F() ;
//通过在父类原型和子类原型之间加入一个临时的构造函数F,切断了子类原型和父类原型之间的联系,这样当子类原型做修改时就不会影响到父类原型。 var parent = new Parent('myParent') ;
var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent
console.log(child.getName()) ; //myChild

打印结果:

可以看到Child的实例child会多嵌套一层。

然后我发现其实可以不使用中间变量F,直接Child.prototype  = new Parent();也可以。

var Parent = function(name){
this.name = name || 'parent' ;
} ;
Parent.prototype.getName = function(){
return this.name ;
} ;
Parent.prototype.obj = {a : 1} ; var Child = function(name){
Parent.apply(this,arguments) ;//通过apply调用父类的构造函数来进行相同的初始化工作
} ;
Child.prototype = new Parent() ; Child.prototype.sayHi = function(){
alert("hi!");
} var parent = new Parent('myParent') ;
var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent
console.log(child.getName()) ; //myChild
parent.sayHi(); //not a function 报错。说明子类的prototype不会影响到父类

这样的问题是:父类构造函数被执行了两次,一次是在子类构造函数中,一次在赋值子类原型时,这是很多余的。

那么是否可以不使用apply,直接var Child  = new Function(); Child.prototype = new Parent();呢……这样绝对不可以!

//这种方法是错误的!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

var Parent = function(name){
this.name = name || 'parent' ;
} ;
Parent.prototype.getName = function(){
return this.name ;
} ;
Parent.prototype.obj = {a : 1} ; var Child = new Function();
Child.prototype = new Parent() ; var parent = new Parent('myParent') ;
var child = new Child('myChild') ; console.log(parent.getName()) ; //myParent
console.log(child.getName()) ; //parent //child是Function对象,其中并没有name属性,所以在new一个Child时,括号内的参数是无效的!!!!

那这种方法不是更容易吗……有什么缺点呢?console.log打印一下parent和child,以及Parent和Child,就会发现问题……

可以看到,打印Parent中是有name属性的,而Child里没有name这一属性。而若是看parent和child两个实例,就可以看到其实例也没有name属性,name是原型的属性,这个意思就是说,如果Child有多个实例,多个实例的name属性都会指向同一个name,而不是私有的。

所以方法就是1和2了  

2. 对象冒充

        function Parent(name){
this.name = name;
this.getName = function(){
return this.name;
}
}
function Child(name,password){
//通过以下3步实现将Parent属性和方法追加到Child中,从而实现继承
//第一步:this.method是作为一个临时的属性,并且指向Parent所指的对象
//第二步:执行this.method方法,即执行Parent所指向的对象函数
//第三步:销毁this.method属性,即此时Child就已经拥有了Parent的所有属性和方法
this.method = Parent;
this.method(name);
delete(this.method); this.password = password;
this.world = function(){
alert(this.password);
}
}
var child = new Child("Mychild","123456");
console.log(child.getName()); //Mychild
child.world(); //

此外可参考博文:http://blog.csdn.net/james521314/article/details/8645815

js怎么实现继承?的更多相关文章

  1. 浅谈JS中的继承

    前言 JS 是没有继承的,不过可以曲线救国,利用构造函数.原型等方法实现继承的功能. var o=new Object(); 其实用构造函数实例化一个对象,就是继承,这里可以使用Object中的所有属 ...

  2. JS创建对象、继承原型、ES6中class继承

    面向对象编程:java中对象的两个基本概念:1.类:类是对象的模板,比如说Leader 这个是泛称领导,并不特指谁.2:实例:实例是根据类创建的对象,根据类Leader可以创建出很多实例:liyi,y ...

  3. js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。

    js最好的继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法. function ClassA(sColor) { this.color = sColor; } Class ...

  4. js模拟实现继承功能

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  5. js中实现继承的几种方式

    首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...

  6. [js]js原型链继承小结

    这是之前总结的, 发现有很多的毛病,就是重点不突出,重新翻看的时候还是得耗费很长时间去理解这玩意. js中的继承 js中什么是类 1,类是函数数据类型 2.每个类有一个自带prototype属性 pr ...

  7. js一种继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法。

    js一种继承机制:用对象冒充继承构造函数的属性,用原型prototype继承对象的方法. function ClassA(sColor) { this.color = sColor; } ClassA ...

  8. 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承

    ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...

  9. JS中的继承(上)

    JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...

随机推荐

  1. 11.20 正则表达式 断言(?=exp)

    今天看源代码,研究了一下qz写的这个方法: // 添加逗号分隔,返回为字符串 comma: function(length) { ) length = ; var source = ('' + thi ...

  2. ES查询-term VS match (转)

    原文地址:https://blog.csdn.net/sxf_123456/article/details/78845437 elasticsearch 中term与match区别 term是精确查询 ...

  3. 避免切换横竖屏Fragment的重复加载导致UI混乱

    当我们切换横竖屏时 Activity的生命周期就会重走一遍,自然 其中的Fragment的生命周期也就重新走了一遍,实践证明 当熄屏 再开屏时 Fragment的生命周期也会重走一遍 解决方案: an ...

  4. 控制请求重复提交的方法总结(Token)

    重复提交的定义: 重复提交指的是同一个请求(请求地址和请求参数都相同)在很短的时间内多次提交至服务器,从而对服务器造成不必要的资源浪费,甚至在代码不健壮的情况还会导致程序出错. 重复提交的原因或触发事 ...

  5. jmeter的各种调用

    1. 开发将dubbo协议的接口转化成了webservices后,jmeter直接添加http请求,输入网址就好,但是这种需要增加开发测试页面的工作量 2.jmeter自身无法调用zk连接服务器(Jm ...

  6. pycrypto 安装 Crypto 报错 error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools

    error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools&quo ...

  7. vba判断文件是否存在的两种方法(转)

    方法1. 用VBA自带的dir()判断,代码如下: 在 Microsoft Windows 中, Dir 支持多字符 (*)和单字符 (?) 的通配符来指定多重文件 Function IsFileEx ...

  8. CNA, FCoE, TOE, RDMA, iWARP, iSCSI等概念及 Chelsio T5 产品介绍 转载

    CNA, FCoE, TOE, RDMA, iWARP, iSCSI等概念及 Chelsio T5 产品介绍 2016年09月01日 13:56:30 疯子19911109 阅读数:4823 标签:  ...

  9. mactype配置

    配合 Firefox 小小设置(改了好多配置,似乎主要是修改了渲染的核心?是叫这个么?把那个Siera?删掉了,就好了)后,效果极佳,我在原有配置的基础上,加大了字重,显示更粗,更明显. 这里是原配置 ...

  10. linux下创建密钥

    1.生成rsa文件 : a)ssh-keygen -t rsa,然后会提示在/root/.ssh/id_rsa这个路径下存放密钥文件 b)进入到/root/.ssh目录下,将id_rsa.pub更改为 ...