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"> ...
随机推荐
- winscp连接后目录名称乱码
1.点击[编辑](点后变为保存按钮)按钮,高级按钮变为可用,点击[高级] 2.文件名utf-8编码,默认为“自动”,勾选为“开启”
- 选题 Scrum立会报告+燃尽图 06
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8678 一.小组情况组长:贺敬文组员:彭思雨 王志文 位军营 杨萍队名:胜 ...
- docker启动redis并使用java连接
一.先查找镜像 docker search redis 二.拉取镜像 docker pull redis三.等待拉取完毕 四.查看拉去的镜像 docker iamges 五.运行redis 连接1:h ...
- Learn The Architecture Memory Management 译文
1.概述 本文档介绍了ARMv8-A架构内存管理的关键——内存地址转换,包括虚拟地址(VA)到物理地址(PA)的转换.页表(或称地址转换表)格式以及TLBs(Translation Lookaside ...
- BOSCH汽车工程手册————混合驱动
首先放一波资源,一千两百多页的pdf 链接:https://pan.baidu.com/s/15IsvHqOFCnqAKwY_SR4-lA提取码:6wmz 混合驱动 混合驱动有串联驱动并联驱动以及两种 ...
- 基于对象的orm跨表查询再练习
model.py from django.db import models # Create your models here. class Book(models.Model): nid = mod ...
- flutter ListView嵌套高度问题
ListView嵌套时高度无法自适应,需要设置高度才可以显示,设置以下属性可以解决上述问题 shrinkWrap: true, physics: NeverScrollableScrollPhysic ...
- Python OOP知识积累
目录 目录 前言 对象 类 面向对象 Python 面向对象编程三个基本特征 封装 继承 继承的作用 泛化与特化 实现继承的方式 多重继承 多态 方法多态 最后 前言 Python是一个功能非常强大的 ...
- 【汇总】PHP 伪协议 利用
日期:2019-07-28 21:24:36 更新: 作者:Bay0net 介绍: 0x01.基本信息 文件包含函数 include() require() include_once() requir ...
- python UI自动化之JS定位
1.话不多说,直接贴入代码 上面的 document.getElementById 可以替换成别的定位方式,比如: 通过name获取:document.getElementsByName 通过标签获取 ...