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. CommandLineRunner and ApplicationRunner

    1. Run spring boot as a standalone application (non-web) <?xml version="1.0" encoding=& ...

  2. mysql 日期辅助表

    MySQL 生成日期表 #.创建一个num表,用来存储数字0 CREATE TABLE num (i int); #.在num表中生成0 ), (), (), (), (), (), (), (), ...

  3. Linux常用命令及操作(第二弹)

    Ctrl l清屏 Ctrl d关闭终端 Ctrl Alt T打开终端 pwd 查看当前的目录 Shift Ctrl C复制 Shift Ctrl V粘贴 Shift Ctrl N打开新的终端 F11 ...

  4. Python 抓取数据存储到Redis中

    redis是一个key-value存储结构.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

  5. RF-创建一个自定义关键字库

    仓库自定义库 这里以Selenium2Library库进行举例说明: 编写一个自定义仓库类(与库文件夹名一致),继承关键字类,指定范围和版本即可. 需要声明__init__. import os fr ...

  6. OpenCV学习笔记(9)——形态学转换

    不同的形态学操作,例如腐蚀,膨胀,开运算,闭运算等 形态学操作是根据图像形状进行的简单操作.一般情况下对二值化图像进行操作.需要的参数有两个,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操 ...

  7. CSS 有序或者无序列表的前面的标记 list-style-type 属性

    例子: <html> <head> <style type="text/css"> ul.none{list-style-type:none} ...

  8. (WPF)360安全卫士界面设计

    点击下载 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation&qu ...

  9. PRISM 4 - RegisterViewWithRegion & Custom Export Attributes

    5down votefavorite   I am using Prism 4 with MEF Extensions and the MVVM pattern. During initializat ...

  10. 阶段3 2.Spring_07.银行转账案例_3 分析事务的问题并编写ConnectionUtils

    不是没有事务造成的 这样相当于有四个connection 每一个都有自己独立的事物 每一个自己成功就提交事务. 已经提交的就执行结束.没有提交的就报异常 让这些操作使用同一个connection 事物 ...