JS中对象继承方式
JS对象继承方式
摘自《JavaScript的对象继承方式,有几种写法》,作者:peakedness
链接:https://my.oschina.net/u/3970421/blog/2872629
方式一:对象冒充
原理:构造函数使用this关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使Parent构造函数称为Children的方法,然后调用它。Children会收到Parent的构造函数中定义的属性和方法。
//父类构造函数
var Parent = function(name){
this.name = name;
this.sayHi = function(){
console.log("Hi" + this.name + ".");
}
}
var Children = function(name){
this.method = Parent;
this.method(name); //实现继承
delete this.method;
this.getName = function(){
console.log(this.name);
}
}
var P = new Parent("john");
var C = new Children("joe");
P.sayHi(); //Hi john
C.sayHi(); //Hi joe
C.getName(); //joe
方式二:原型链继承
原理:JS是一门基于原型的语言。在JS中prototype对象的任何属性和方法都被传递给那个类的所有实例。
//父类构造函数
var Parent = function(name){
this.name = name;
this.sayHi = function(){
console.log("Hi" + this.name + ".");
}
}
//子类构造函数
var Children = function(){};
Children.prototype = new Parent();
var P = new Parent();
var C = new Children();
P.sayHi();
C.sayHi();
注意:
调用Parent的构造函数,没有给它传递参数。这是原型链中的标准做法,要确保构造函数没有任何参数。
方式三:使用call或apply方法
原理:通过改变this指向实现继承。apply第二个参数必须是数组,call依次传入。
//父类构造函数
var Parent = function(name){
this.name = name;
this.sayHi = function(){
console.log("Hi" + this.name + ".");
}
};
//子类构造函数
var Children = function(name){
Parent.call(this,name);
this.getName = function(){
console.log(this.name);
}
};
var C = new Children("Joe");
C.sayHi(); //Hi john
C.getName(); //Joe
方式四:混合使用(推荐)
使用原型链就无法使用带参数的构造函数了
因此,在JS中创建类,最好使用构造函数定义属性,使用原型链定义方法。
//父类构造函数
var Parent = function(name){
this.name = name;
}
Parent.prototype.sayHi = function(){
console.log("Hi ! " + this.name + "!!!");
}
var P = new Parent("John");
P.sayHi(); //Hi John !!!
方式五:使用Object.create方法
Object.create方法会使用指定的原型对象及其属性去创建一个新的对象
//父类构造函数
var Parent = function(name){
this.name = name;
}
Parent.prototype.sayHi = function(){
console.log("Hi " + this.name + ".");
}
//子类构造函数
var Children = function(name,age){
this.age = age;
Parent.call(this,name); //属性不在prototype上
};
Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
Children.prototype.getAge = function(){
console.log(this.age);
};
var P = new Parent("John");
var C = new Children("Joe",30);
P.sayHi(); //Hi John
C.sayHi(); //Hi Joe
C.getAge(); //30
注意:
当执行Children.prototype = Object.create(Parent.prototype)这个语句后,Children的constructor就被变为Parent,因此需要将Children.protype.constructor重新指定为Children本身。
constructor指向创建此对象的函数的引用。
方式六:extends关键字实现继承
class Paren{
constructor(name,age){
this.name = name;
this.age = age;
}
}
class Children extends Parent{
constructor(name,age,job){
super(name,age); //super必须在前,否则代码报错
this.job = job;
}
}
注意:
子类的constructor方法没有调用super之前,就使用this关键字会报错。原因是:子类Children的构造函数之中的super(),代表调用父类Parent的构造函数。
super虽然代表了父类Parent的构造函数,但是返回的是子类Children的实例,即super内部的this指的是Children,因此super()在这里相当于Parent.prototype.constructor.call(this);
JS中对象继承方式的更多相关文章
- JS中的继承方式总结
1. 原型链继承(又称类继承) Child.prototype = new Parent(); function Parent (name, age) { this.name = name; this ...
- js中对象继承的冒充方法
function Parent(name){ this.name = name; this.sayName = function(){ console.log(this.name); } } func ...
- js中常见继承方式
1.原型模式 function Father(){ this.property = true; } Father.prototype.getValue = function(){ return thi ...
- js中的继承和重载
js中有三种继承方式:一.通过原型(prototype)实现继承 二.借用构造函数式继承,可分为通过call()方法实现继承和通过apply()方法实现继承 仅仅通过原型继承我们可以发现在实例化子 ...
- js中实现继承的几种方式
首先我们了解,js中的继承是主要是由原型链实现的.那么什么是原型链呢? 由于每个实例中都有一个指向原型对象的指针,如果一个对象的原型对象,是另一个构造函数的实例,这个对象的原型对象就会指向另一个对象的 ...
- 【学习笔记】六:面向对象的程序设计——理解JS中的对象属性、创建对象、JS中的继承
ES中没有类的概念,这也使其对象和其他语言中的对象有所不同,ES中定义对象为:“无序属性的集合,其属性包含基本值.对象或者函数”.现在常用的创建单个对象的方法为对象字面量形式.在常见多个对象时,使用工 ...
- js中对象转化成字符串、数字或布尔值的转化规则
js中对象可以转化成 字符串.数字.布尔值 一.对象转化成字符串: 规则: 1.如果对象有toString方法,则调用该方法,并返回相应的结果:(代码通常会执行到这,因为在所有对象中都有toStrin ...
- 【转载】js中对象的使用
原文链接:http://www.jb51.net/article/90256.htm[侵删] 简单记录javascript中对象的使用 一.创建对象 //创建一个空对象 var o={}; //创建一 ...
- JS中的继承(上)
JS中的继承(上) 学过java或者c#之类语言的同学,应该会对js的继承感到很困惑--不要问我怎么知道的,js的继承主要是基于原型(prototype)的,对js的原型感兴趣的同学,可以了解一下我之 ...
随机推荐
- node.js获取cookie
node.js 获取cookie var Cookies ={}; if (req.headers.cookie != null) { req.headers.cookie.split(';').fo ...
- shell 复制/备份文件 脚本
#!/bin/sh # author hapday # -- echo "以时间日期为名称基准备份 war 包." date +%Y-%m-%d-%H-%M-%S cp artup ...
- Ubuntu16.04安装Docker1.12+开发实例+hello world+web应用容器
本次主要是详细记录Docker1.12在Ubuntu16.04上的安装过程,创建Docker组(避免每次敲命令都需要sudo),Docker常用的基本命令的总结,在容器中运行Hello world,以 ...
- Entity Framework:“无法加载指定的元数据资源
System.Data.Entity.Core.MetadataException:“无法加载指定的元数据资源 CodeFirst方式使用EF,写入数据时报错.System.Data.Entity.C ...
- SharePoint2010 HTTP Error 503. The service is unavailable 解决方法
1.更改系统管理员用户密码前提 因为更改系管理员用户密码会影响到 "SharePoint2010"正常运行,所在尽量不要更改系统管理员用户的密码, 必须更改密码的话,需要注意以两点 ...
- (五)TortoiseSVN 客户端-----安装
svn客户端类型 svn客户端需要通过网络访问svn服务端提交文件.查询文件等,可通过以下客户端类型访问svn服务端: 使用Subversion提供的客户端命令,使用方式:在命令行下输入命令操作. 使 ...
- C# 任务并行库使用小计 z
1.简单创建使用 using System; using System.Diagnostics; using System.Threading; using System.Threading.Task ...
- 创建Spark镜像文件
创建Spark镜像文件 1.将spark容器提交到新的镜像中 $>docker commit 01a25bdf1499 myrepos:centos-spark 2.将centos-spark镜 ...
- 常见协议TCP、UDP、IP图
ip tcp udp icmp help ip tcp http icmp
- 获取v$latch数据源实验
实验环境:Oracle Rac 11.2.0.3 首先获取v$latch的定义:通过PL/SQL或者get ddl等常规途径只能获取到v_$latch相关的视图信息.需要通过特殊方法获取v$latch ...