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中对象继承方式的更多相关文章

  1. JS中的继承方式总结

    1. 原型链继承(又称类继承) Child.prototype = new Parent(); function Parent (name, age) { this.name = name; this ...

  2. js中对象继承的冒充方法

    function Parent(name){ this.name = name; this.sayName = function(){ console.log(this.name); } } func ...

  3. js中常见继承方式

    1.原型模式 function Father(){ this.property = true; } Father.prototype.getValue = function(){ return thi ...

  4. js中的继承和重载

      js中有三种继承方式:一.通过原型(prototype)实现继承 二.借用构造函数式继承,可分为通过call()方法实现继承和通过apply()方法实现继承 仅仅通过原型继承我们可以发现在实例化子 ...

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

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

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

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

  7. js中对象转化成字符串、数字或布尔值的转化规则

    js中对象可以转化成 字符串.数字.布尔值 一.对象转化成字符串: 规则: 1.如果对象有toString方法,则调用该方法,并返回相应的结果:(代码通常会执行到这,因为在所有对象中都有toStrin ...

  8. 【转载】js中对象的使用

    原文链接:http://www.jb51.net/article/90256.htm[侵删] 简单记录javascript中对象的使用 一.创建对象 //创建一个空对象 var o={}; //创建一 ...

  9. JS中的继承(上)

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

随机推荐

  1. Web程序中使用EasyUI时乱码问题

    今天偶然遇见使用easyUI时,弹窗和分页都是乱码的问题,耗费了很长的时间来解决,以此记住这个坑. 相信大家都会在使用easyUI时都会设置这样一句: 那么就有可能出现设置中文后的乱码问题,如下图: ...

  2. 移除script标签引起的兼容性问题

    一.应用场景: 有时候我们需要动态创建script标签实现脚本的按需加载,我们会为script标签绑定onload或者onreadystatechange事件,用于检测动态脚本是否加载并执行完毕,在事 ...

  3. PAT 1064 Complete Binary Search Tree

    #include <iostream> #include <cstdio> #include <cstdlib> #include <vector> # ...

  4. js匿名函数使用&传参

    function () { alert("error"); } //报错:匿名函数不能直接调用 使用 0x01 (function () { alert("Success ...

  5. html表格设置

    表格 表格由 <table> 标签来定义.每个表格均有若干行(由 <tr> 标签定义),每行被分割为若干单元格(由 <td> 标签定义).字母 td 指表格数据(t ...

  6. SQL Server ->> 生成时间类型的Partition Function和Partition Scheme代码

    有时工作中要建个分区函数,可是像日期这种分区函数要是搞个几百个的值那不是要搞死我.于是写了点代码自动生成一个从1990年开始的按月的分区函数和对应的分区主题 USE [TestDB] GO DECLA ...

  7. 在Eclipse中安装JSHint插件

    离线安装 1.下载插件包 http://download.eclipsesource.com/~rsternberg/jshint-eclipse-0.9.8.20130728-0004-b94b44 ...

  8. 【转】异步的AsyncHttpClient使用详解

    http://blog.csdn.net/angjunqiang/article/details/55259170 背景 前面的一篇文章[同步的HttpClient使用详解]中,提到了服务端通进行网络 ...

  9. js和.net操作Cookie遇到的问题

    Cookie初探1.我理解中的Cookie1.1.Cookie存储位置是客户端的1.2.Cookie存储数据,数据大小也是有限制的 2.Cookie的用法2.1.js对Cookie的操作(网上很多我就 ...

  10. 【洛谷P1005】矩阵取数游戏

    矩阵取数游戏 题目链接 每行分别跑一趟区间DP即可 这道题区间DP是非常裸的,按套路来即可 但是很毒瘤的是需要高精度, “我王境泽就是爆零,从这跳下去,也不会用__int128的!” #include ...