javascript 继承的两种方式
js中继承可以分为两种:对象冒充和原型链方式
一、对象冒充包括三种:临时属性方式、call()及apply()方式
1.临时属性方式
代码如下:
this.name = name;
this.say = function(){
alert('My name is '+this.name);
}
}
function F2E(name,id){
this.temp = Person;
this.temp(name);
delete this.temp;
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
var simon = new F2E('Simon',9527);
simon.say();
simon.showId();
2.call()/apply()方式
实质上是改变了this指针的指向
this.name = name;
this.say = function(){
alert('My name is '+this.name);
}
}
function F2E(name,id){
Person.call(this,name); //apply()方式改成Person.apply(this,new Array(name));
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
var simon = new F2E('Simon',9527);
simon.say();
simon.showId();
缺点:先来看这么一张内存分配图:
在OO概念中,new实例化后,对象就在堆内存中形成了自己的空间,值得注意的是,这个代码段。而成员方法就是存在这个代码段的,并且方法是共用的。问题就在这里,通过对象冒充方式继承时,所有的成员方法都是指向this的,也就是说new之后,每个实例将都会拥有这个成员方法,并不是共用的,这就造成了大量的内存浪费。并且通过对象冒充的方式,无法继承通过prototype方式定义的变量和方法,如以下代码将会出错:
this.name = name;
this.say = function(){
alert('My name is '+this.name);
}
}
Person.prototype.age = 20;
Person.prototype.sayAge = function(){alert('My age is '+this.age)};
function F2E(name,id){
Person.apply(this,new Array(name));
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
var simon = new F2E('Simon',9527);
simon.sayAge(); //提示TypeError: simon.sayAge is not a function
二、原型链方式
this.name = 'Simon';
}
Person.prototype.say = function(){
alert('My name is '+this.name);
}
function F2E(id){
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
F2E.prototype = new Person();
var simon = new F2E(9527);
simon.say();
simon.showId();
alert(simon.hasOwnProperty('id')); //检查是否为自身属性
接下来按照上面的例子来理解以下js原型链概念:
原型链可以理解成:js中每个对象均有一个隐藏的__proto__属性,一个实例化对象的__proto__属性指向其类的prototype方法,而这个prototype方法又可以被赋值成另一个实例化对象,这个对象的__proto__又需要指向其类,由此形成一条链,也就是前面代码中的
这句是关键。js对象在读取某个属性时,会先查找自身属性,没有则再去依次查找原型链上对象的属性。也就是说原型链的方法是可以共用的,这样就解决了对象冒充浪费内存的缺点。
下面再来说缺点:
缺点显而易见,原型链方式继承,就是实例化子类时不能将参数传给父类,也就是为什么这个例子中function Person()没有参数,而是直接写成了this.name=”Simon”的原因。下面的代码将不能达到预期的效果:
this.name = name;
}
Person.prototype.say = function(){
alert('My name is '+this.name);
}
function F2E(name,id){
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
F2E.prototype = new Person();
var simon = new F2E("Simon",9527);
simon.say();
simon.showId();
function Person(name){
this.name = name;
}
Person.prototype.say = function(){
alert('My name is '+this.name);
}
function F2E(name,id){
this.id = id;
this.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
}
F2E.prototype = new Person(); //此处无法进行传值,this.name或者name都不行,直接写F2E.prototype = new Person('wood')是可以的,但是这样的话simon.say()就变成了My name is wood
var simon = new F2E("Simon",9527);
simon.say(); //弹出 My name is undefined
simon.showId();
最后,总结一下自认为较好的继承实现方式,成员变量采用对象冒充方式,成员方法采用原型链方式,代码如下:
this.name = name;
}
Person.prototype.say = function(){
alert('My name is '+this.name);
}
function F2E(name,id){
Person.call(this,name);
this.id = id;
}
F2E.prototype = new Person();
//此处注意一个细节,showId不能写在F2E.prototype = new Person();前面
F2E.prototype.showId = function(){
alert('Good morning,Sir,My work number is '+this.id);
}
var simon = new F2E("Simon",9527);
simon.say();
simon.showId();
javascript 继承的两种方式的更多相关文章
- 总结javascript继承的两种方式的N中写法
最近翻看博客园,总结了一下javascript的继承方式:prototype和copy继承方式. 一.prototype方式 当一个函数被创建时,Function构造函数产生的函数会隐式的被赋予一个p ...
- Flex(ActionScript)与JavaScript交互的两种方式示例
随着各单位部门信息化进程的不断发展,互通互联.共享协调不断的被越来越多的客户所重视.很多新项目都要去必须能够集成已有的早期系统,至少也要能够实现交互对接.今天跟大家分享的是系统对接中ActionScr ...
- js实现继承的两种方式
这是面试时面试官会经常问到问题: js的继承方式大致可分为两种:对象冒充和原型方式: 一.先说对象冒充,又可分为3种:临时属性方式.call().apply(): 1.临时属性方式: 当构造对象son ...
- js-使用JavaScript、jQuery两种方式实现全选/全不选
html代码 <input type='checkbox' value="10" name="frust"/>苹果10元 <br/> & ...
- 模块化Javascript代码的两种方式
1.将模块整体放在函数里 function buildMonthNameModule() { var names = ["January ", "February&quo ...
- python类的继承的两种方式
class Animal(object): """docstring for Animal""" def __init__(self, na ...
- JavaScript输出的两种方式
var a="Hello World" document.write(a) //在网页上输出:Hello World var a="Hello World" c ...
- javascript中对象两种创建方式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- VS Code - Debugger for Chrome调试JavaScript的两种方式
VS Code - Debugger for Chrome调试JavaScript的两种方式 最近由于出差的缘故,博客写的不是很多,一直想写一篇VS Code - Debugger for Chrom ...
随机推荐
- django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统
Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...
- day5笔记 列表 list 增删改查
列表的使用 一.索引和切片 # 索引和切片,用法与字符串一样 l = [1,2,3,'af','re',4,'45'] print(l[0]) print(l[3]) print(l[-1]) # ' ...
- maven的相关命令
maven的相关命令 mvn archetype:create :创建 Maven 项目 mvn compile :编译源代码(编译到target文件夹中) mvn test-compile :编译测 ...
- nodejs入门-做一个代理服务器
看到node.js的httpServer和http.request,第一个想法居然是可以用它做一个代理服务器下面代码,实现了代理的基本功能,通过网络的代理设置将你的浏览器的请求转到这个httpServ ...
- application/x-www-form-urlencoded和multipart/form-data
我们在提交表单的时候,form表单参数中会有一个enctype的参数. EncType表明提交数据的格式,用 Enctype 属性指定将数据发到服务器时浏览器使用的编码类型. enctype指定了H ...
- Python3.x:pip install pymssql安装时出错
Python3.x:pip install pymssql安装时出错 一.错误日志 error: Microsoft Visual C++ 14.0 is required. Get it with ...
- zabbix3.0安装(本文引用51cto博主烂泥行天下的文章,我也是参考他写的文章安装的zabbix)
但是由于他文章写的时间有点久了,上面的关于安装zabbix之前需要安装的zabbix3.0yum源的链接失效了,所有我找了2个能用的zabbix 3.0yum源,其他的就不再写了 安装zabbix3. ...
- 配置内核 Makefile:1449: *** mixed implicit and normal rules. Stop.【转】
本文转载自:https://blog.csdn.net/bitowang/article/details/8446494 在编译内核的时候提示Makefile:1449: *** mixed impl ...
- 《Maven实战》第13章 版本管理
版本管理:项目整体版本的演变过程的管理,如从1.0-SNAPSHOT到1.0,再到1.1-SNAPSHOT 版本控制:借助版本控制工具追踪代码的每一个变更 13.1什么是版本管理 版本管理:项目整体版 ...
- 使用MyCat分表分库原理分析
Mycat可以实现 读写分离 分表分库 主从复制是MySQL自带的哈~ 关于分片取模算法: 根据id进行取模 根据数据库集群的数量(或者说是表数量,mycat里面一个表对应一个库) 使用MyCat ...