https://juejin.im/post/5cfd9d30f265da1b94213d28#heading-14

https://juejin.im/post/5d124a12f265da1b9163a28d

https://juejin.im/post/5b44a485e51d4519945fb6b7#heading-19

//1.原型链继承  与Object.create()一样
// 特点(1)通过原型来实现继承时,原型会变成另一个类型的实例;子实例会混入父实例的方式与属性
// 原先的实例属性变成了现在的原型属性,该原型的引用类型属性会被所有的实例共享。
// (2)在创建子类型的实例时,没有办法在不影响所有对象实例的情况下给超类型的构造函数中传递参数
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(role){
this.crole=role;
this.name=role+'999' //新的实例对象里原型会包含父实例的属性方法;子实例会再次赋值
}
Child.prototype=new Parent('wade','papa');
var child1=new Child('child1')
child1.color.push('white'); //color: (5) ["red", "yellow", "hotpink", "white", "white"]
console.log(child1) //Child {crole: "child1", name: "child1999"} var child2=new Child('child2')
child2.color.push('white'); //color: (5) ["red", "yellow", "hotpink", "white", "white"]
console.log(child2) //Child {crole: "child2", name: "child2999"} // 2.借助构造函数
// (1)解决了原型中包含引用类型值被所有实例共享的问题;但没继承父类的原型
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
var child1=new Child('ken','child1');
child1.color.push('white')
console.log(child1)
var child2=new Child('peter','child2');
child2.color.push('white')
console.log(child2) // 3.组合继承(原型链 + 借用构造函数)
// 基本思路:使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承,
// 既通过在原型上定义方法来实现了函数复用,又保证了每个实例都有自己的属性。可以继承实例属性/方法,也可以继承原型属性/方法
// (1)new了两次 而且new父类会造成父类的实例无用属性挂在在子类实例的原型上
// (2)可以向超类传递参数;每个实例都有自己的属性;实现了函数复用
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
Child.prototype=new Parent();
Child.prototype.constructor=Child; var child1=new Child('ken','child1');
child1.color.push('white')
console.log(child1)
var child2=new Child('peter','child2');
child2.color.push('white')
console.log(child2) //3-1组合继承优化 减少new父类实例添加多余的属性方法到子类实例的原型上
// child1 instanceOf Parent =>true child1 instanceOf Child =>true
// 可用 child1.constructor去找
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
Child.prototype=Parent.prototype;
Child.prototype.constructor=Child;
var child1=new Child('ken','child1');
// 3-2组合继承优化
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
Child.prototype=Object.create(Parent.prototype);
Child5.prototype.constructor = Child5;
var child1=new Child('ken','child1');
// 4.寄生组合继承
// 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性
// 只调用了一次超类构造函数,效率更高。避免在Child.prototype上面创建不必要的、多余的属性,与其同时,
// 原型链还能保持不变。 因此寄生组合继承是引用类型最理性的继承范式。
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
(
function(){
function F(){}
F.prototype=Parent.prototype;
Child.prototype=new F();
}
)()
var child1=new Child('ken','child1'); // 5寄生式组合
function parasitic(target){
function F(){}
F.prototype=target.prototype;
return new F();
}
function createAnother(target){
var resultPrototype=parasitic(target);
resultPrototype.sayHi=function(){
console.log('hi');
}
return resultPrototype;
}
function Parent(name,role){
this.name=name;
this.role=role;
this.color=['red','yellow','hotpink']
}
Parent.prototype.getName=function(){return this.name};
function Child(name,role){
Parent.call(this,name,role)
}
Child.prototype=createAnother(Parent);
Child.prototype.constructor=Child;
var child1=new Child('ken','child1');

ES6 的 class 允许子类继承父类的静态方法和静态属性:

class MyParent{
static role='parent';
static getRole=()=>{return this.role}
} MyParent.getRole() //parent class Mychild extends MyParent{}
Mychild.getRole() //"parent"
静态属性与方法:https://www.jb51.net/article/126399.htm
Object.setPrototypeOf(obj, proto),用来将obj.__proto__设置为proto
Object.getPrototypeOf(obj),返回obj.__proto__
function Parent(){
this.name='i am parent test';
};
Parent.role="parent111";
Parent.getRole=function(){return this.role};
let temObj=Object.setPrototypeOf({},Parent); //等效于 {}.__proto__=Parent return{}

Object.create(proto, [propertiesObject])    //方法创建一个新对象,并且该对象继承了proto。其实第一个参数可以理解为添加到原型上的,第二个参数理解为添加到实例对象上的

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create

https://www.jianshu.com/p/28d85bebe599

// Shape - 父类(superclass)
function Shape() {
this.x = 0;
this.y = 0;
} // 父类的方法
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
}; // Rectangle - 子类(subclass)
function Rectangle() {
Shape.call(this); // call super constructor.
} // 子类续承父类
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'

ES6继承

function Parent(){
this.role='parent';
this.color=['red','black','hotpink']
}
Parent.prototype.giveMoney=()=>{console.log('$100')}; var parent1=new Parent(); var child1=Object.create(Object.getPrototypeOf(parent1),Object.getOwnPropertyDescriptors({cRole:'child'}))
child1.cRole
child1.giveMoney() // $100

Class的super ,分两种情况 https://www.jb51.net/article/126399.htm

1、当作函数使用

class A {
constructor() {
console.log(new.target.name); //new.target指向当前正在执行的函数
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B super虽然代表了父类A的构造函数,但是返回的是子类B的实例,即super内部的this指的是B,因此super()在这里相当于A.prototype.constructor.call(this)。

2、当作对象使用,这里也有存和取的区别,存的时候相当于super.x==this.x;取的时候是在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

class A {
c() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.c()); // 2 super在普通方法之中,指向A.prototype,所以super.c()就相当于A.prototype.c()。
}
}
let b = new B();
//通过super调用父类的方法时,super会绑定子类的this。
class A {
constructor() {
this.x = 1;
}
s() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.s();
}
}
let b = new B();
b.m() // 2 super.s() == A.prototype.s.call(this)
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3;
console.log(super.x); // undefined
console.log(this.x); //
}
}
let b = new B();
//super.x赋值为3,这时等同于对this.x赋值为3。而当读取super.x的时候,读的是A.prototype.x,所以返回undefined。

js 继承,Object.setPrototypeOf | Object.getPrototypeOf | Object.create class的更多相关文章

  1. js中的new操作符与Object.create()的作用与区别

    js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...

  2. Object.create 以及 Object.setPrototypeOf

    第一部分 Object.crate() 方法是es5中的关于原型的方法, 这个方法会使用指定的原型对象以及属性去创建一个新的对象. 语法 Object.create(proto, [ properti ...

  3. Object.setPrototypeOf() 与Object.getPrototypeOf() 方法的使用

    Object.setPrototypeOf 方法的使用 [1] 将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 语法 Object.setProto ...

  4. [terry笔记]IMPDP报错ORA-39083 Object type TYPE failed to create ORA-02304

    今天在使用impdp导入的时候(同一数据库中转换schema),遇到了 ORA-39083: Object type TYPE failed to create with error: ORA-023 ...

  5. Object.setPrototypeOf 方法的使用

    将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 语法 Object.setPrototypeOf(obj, prototype) 参数 obj 将被 ...

  6. Object type TYPE failed to create with error

    ORA-39083: Object type TYPE failed to create with error: ORA-02304: invalid object identifier litera ...

  7. impdp报错ORA-39083 ORA-02304 Object type TYPE failed to create

    环境Red Hat Enterprise Linux Server release 5.8 (Tikanga)ORACLE Release 11.2.0.3.0 Production 我用expdp, ...

  8. JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)

    JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...

  9. ES6 Object.setPrototypeOf ()方法和defineProperty()方法的使用

    将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 示例: <script type="text/javascript"> ...

随机推荐

  1. Redis Cluster with SpringBoot

    前提: 按照 https://www.cnblogs.com/luffystory/p/12081074.html 配置好Redis Cluster in Ubuntu 按照如下结构搭建项目结构: P ...

  2. jsp里面自定义标签常量详解

    标签中静态常量: EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流 SKIP_BODY:告诉服务器不要处理正文内容 EVAL_PAGE:让服务器继续执行页面 SKIP_ ...

  3. shell定义

    用户输入的命令并且把它们送到内核.不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序. Shell编程语言具有普通编程语言的很多特点 无图形化界面时与lin ...

  4. Java多线程核心知识

    多线程相对于其他 Java 知识点来讲,有一定的学习门槛,并且了解起来比较费劲.在平时工作中如若使用不当会出现数据错乱.执行效率低(还不如单线程去运行)或者死锁程序挂掉等等问题,所以掌握了解多线程至关 ...

  5. Apache配置转发

    第一种: LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_htt ...

  6. Oracle 递归查询 (start with ...connect by ...prior)

    1.connect by 是结构化查询中用到的,其基本语法是:select … from tablename start with 条件1connect by 条件2where 条件3;例:selec ...

  7. ubuntu 16.04 安装最新的 docker

      转载地址:https://www.cnblogs.com/tianhei/p/7802064.html 本文将介绍在ubuntu16.04系统下安装和升级docker.docker-compose ...

  8. golang context学习记录1

    1.前言 一个请求,可能涉及多个API调用,多个goroutine,如何在多个API 之间,以及多个goroutine之间协作和传递信息,就是一个问题. 比如一个网络请求Request,需要开启一些g ...

  9. iOS 的 Gif 渲染

    关于gif的展示,有些项目中很少用到,所以有的人对于这方面了解不是很多 下面介绍几种展示gif的方法,希望大家可以用得上,有更好的方法欢迎评论区留言 一,展示本地的gif,使用的SDWebImage里 ...

  10. Java学习之==>面向对象编程 Part2

    一.封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结 ...