js 继承,Object.setPrototypeOf | Object.getPrototypeOf | Object.create class
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的更多相关文章
- js中的new操作符与Object.create()的作用与区别
js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...
- Object.create 以及 Object.setPrototypeOf
第一部分 Object.crate() 方法是es5中的关于原型的方法, 这个方法会使用指定的原型对象以及属性去创建一个新的对象. 语法 Object.create(proto, [ properti ...
- Object.setPrototypeOf() 与Object.getPrototypeOf() 方法的使用
Object.setPrototypeOf 方法的使用 [1] 将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 语法 Object.setProto ...
- [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 ...
- Object.setPrototypeOf 方法的使用
将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 语法 Object.setPrototypeOf(obj, prototype) 参数 obj 将被 ...
- Object type TYPE failed to create with error
ORA-39083: Object type TYPE failed to create with error: ORA-02304: invalid object identifier litera ...
- 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, ...
- JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)
JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...
- ES6 Object.setPrototypeOf ()方法和defineProperty()方法的使用
将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性). 示例: <script type="text/javascript"> ...
随机推荐
- JavaScript疑难杂症系列-事件
事件这块知识点虽然是老生长谈的,但对于我来说多多整理,多多感悟,温故知新,每次看看这块都有不同的收获.(在这里我不会长篇大论,只会挑重点;具体的小伙伴们自行查找) 什么是事件 在编程时系统内发生的动作 ...
- Struts2理解?
(1)Struts2是一个基于MVC设计模式的Web应用框架,在MVC设计模式中Struts2作为控制器(Controller)来建立模型与视图的数据交互. Struts 2以WebWork为核心,采 ...
- C++入门经典-例3.14-使用while循环计算从1到10的累加
1:代码如下: // 3.14.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> usin ...
- JavaScript Thread.Sleep()
What is the JavaScript version of sleep()? Since 2009 when this question was asked, JavaScript has e ...
- ffmpeg修复时间戳
ffmpeg -re -i e:/media/baifa.mp4 -filter_complex -hls_wrap -hls_time d:/demo/hls/cctv13/playlist.m3u ...
- 使用ViewPager实现广告自动轮播的效果
package com.loaderman.viewpgerlunbodemo; import android.os.Bundle; import android.os.Handler; import ...
- redis源码分析之数据结构:跳跃表
跳跃表是一种随机化的数据结构,在查找.插入和删除这些字典操作上,其效率可比拟于平衡二叉树(如红黑树),大多数操作只需要O(log n)平均时间,但它的代码以及原理更简单. 和链表.字典等数据结构被广泛 ...
- jqGrid细节备注—jqGrid中自定义格式,URL格式
本文来自:http://cnn237111.blog.51cto.com/2359144/782137 jqGrid中自定义格式,URL格式 当官方自带的showlink用起来不是十分顺手,因此可以考 ...
- 破解root
启动grub按E,进入编辑,ro 改为 rw init=/sysroot/bin/sh然后Ctrl+X进入单用户# chroot /sysroot# passwd root# touch /.auto ...
- git 新建项目提交本地项目代码
git init git remote add origin ssh://git@42.123.127.93:10022/tyshawn/sdap1.git git add . git commit ...