JS 之 对象、继承

news2024/11/18 12:38:48

目录

JS对象

1.通过new Object()创建

2.工厂模式

3.构造函数模式

4.原型模式

5.组合使用构造函数与原型对象

6.动态原型模式

7. 寄生构造函数模式

8.稳妥构造函数模式

原型对象

原型链

继承

1.原型链继承

2.借用构造函数(经典继承 | 伪造函数)

3.组合继承

4.原型式继承

5.寄生式继承

class(ES6)

constructor 方法

prototype属性

取值函数(getter)与存值函数(setter)

class的其他定义方式

 注意点

继承(ES6)


JS对象

js对象拥有属性和方法

1.通过new Object()创建

person=new Object();
person.firstname="John";
person.lastname="Doe";
person.age=50;
console.log(person)
// { firstname: 'John', lastname: 'Doe', age: 50 }

2.工厂模式

这种模式抽象了创建具体对象的过程,通过一个接口来创建对象 ;不能体现是谁创造的实例

function Person(name, age){
    var o = new Object();
    o.name = name;
    o.age = age;
    return o;
}

var person1 = Person('lhf', 25);
console.log(person1.name);
//不能判断实例的类型,实例继承了谁
console.log(person1 instanceof Person);  

3.构造函数模式

与普通函数的区别,调用它们的方式不同;任何函数,只要通过new操作符来调用,那么就可以成为构造函数。

function Person(name, age){
    this.name = name;
    this.age = age;
    this.getName = function(){
        console.log(this.name)
    };
}

var person1 = new Person('lhf', 25);
console.log(person1.name) // { name: 'lhf', age: 25 }
console.log(person1 instanceof Person);  //true,可以体现实例来自哪里

 person1对象有一个构造属性,该属性指Person

console.log(person1.constructor === Person); // true

与工厂模式的不同是:

没有在函数中创建对象,通过new操作符创建;

没有return语句,直接将属性和方法赋值给this;

工厂模式不能体现是谁创造的实例,构造函数可以(优点)

使用new操作符,经历的步骤:

创建一个新对象;

将构造函数的作用域赋值给新对象,即将this指向新创建的对象obj; 

执行构造函数中的代码,为这个新对象添加属性;

返回新对象;

缺点:

每个方法都要在每个实例上重新创建一遍

当我们把方法移到外面时,属性getName是一个指向函数的指针,因此实例就共享了全局作用域中的函数。

问题好像是解决了,但又产生了新的问题:如果要定义很多方法,那么就要定义很多全局函数,这样就无法封装。

function Person(name, age){
    this.name = name;
    this.age = age;
    this.getName = getName;  // 存放的是一个指向函数的指针
}
function getName(){
    console.log(this.name)
};

4.原型模式

原型模式指我们创建的每个函数都有一个原型(prototype)属性,这个属性是一个指针,指向一个对象,而这个对象包含所有实例共享的方法和实例。

使用原型的好处:让所有对象共享它所包含的原型和方法

原型对象的缺点:

  • 它省略了构造函数传参这一环节,导致所有实例在默认情况下的属性值相同;
  • 对于共享的引用类型(函数),当一个实例改变引用类型的值时,其他实例也会改变;
function Person() {
}
Person.prototype.name = "lhf";
Person.prototype.age = 24;
Person.prototype.getName = function(){
  console.log(this.name);
}
// 通过new创建一个实例
var person1 = new Person();
console.log(person1.name+mine.age);  // 输出 lhf24
person1.getName();                   //lhf

建议此时先看(原型对象)

5.组合使用构造函数与原型对象

优点:每个实例可以拥有属于自己的属性值,同时也可以通过原型属性,拥有公共的属性值

function Person(name, age) {
  this.age=age;
  this.name=name;
}
Person.prototype.location = '中国';
var person1 = new Person('lhf', 24);
var person2 = new Person('zuzu', 24);
console.log(person1.name+' '+person1.location);
console.log(person2.name+' '+person2.location);
// lhf 中国
// zuzu 中国

6.动态原型模式

把构造函数模式与原型模式合二为一,location只在初次调用构造函数时执行一次

function Person(name, age) {
  this.age=age;
  this.name=name;
  console.log(this.location);
  if(this.location == undefined){
    Person.prototype.location = '中国';
  }
}
var person1 = new Person('lhf', 24);  //undefined
var person2 = new Person('zuzu', 24); //中国 

7. 寄生构造函数模式

这种模式的思想是创建一个函数,仅仅用来封装创建对象的代码。该模式返回的对象与构造函数没有关系。

与工厂模式的不同点,使用new操作符,并且把包装的函数叫做构造函数

function Person(name, age){
  var o = new Object();
  o.name = name;
  o.age = age;
  return o;
}

var person1 = new Person('lhf', 25);
console.log(person1.name);

8.稳妥构造函数模式

稳妥推向,指的是没有公共属性,而且其方法也不引用this的对象,可以防止数据被其他应用程序改动。与寄生构造函数模式类似,但是有两点不同:1.创建对象的实例方法不引用this  2.不使用new操作符调用构造函数。

function Person(name, age){
  var o = new Object();
  o.getName = function(){
    return name;
  }
  return o;
}

var person1 = new Person('lhf', 25);
console.log(person1.getName()); //lhf

原型对象

  1. 无论什么时候,只要创建了一个新函数,就会同时创建一个prototype属性(指针),指向函数的原型对象;
  2. 默认情况下,所有原型对象都会获取一个constructor(构造函数)属性(指针),指向prototype属性所在函数;通过constructor,我们可以知道该原型对象引用于哪个构造函数;
  3. 实例都包含一个内部指针__proto__,指向原型对象
function Person() {
}
//添加原型属性及方法
Person.prototype.name = "lhf";
Person.prototype.age = 24;
Person.prototype.getName = function(){
  console.log(this.name);
}

var person1 = new Person();
// 1、3
console.log(Person.prototype); //{ name: 'lhf', age: 24, getName: [Function (anonymous)] }
console.log(person1.__proto__); //{ name: 'lhf', age: 24, getName: [Function (anonymous)] }
console.log(Object.getOwnPropertyNames(Person.prototype)); //[ 'constructor', 'name', 'age', 'getName' ]

// 2 通过constructor,我们可以知道该原型对象引用于哪个构造函数
console.log(Person.prototype.constructor === Person); // true

// 重写原型,无constructor
// 表示把Person函数的Prototype指针指向了另一个地址,原来的地址只被Person1引用
Person.prototype = {
  name: "zuzu",
  age: 12,
  getName: function () {
    console.log(this.name);
  }
};
console.log(Person.prototype.constructor === Person); // false
console.log(Object.getOwnPropertyNames(Person.prototype)); //[ 'name', 'age', 'getName' ]
console.log(Person.prototype);  //{ name: 'zuzu', age: 12, getName: [Function: getName] }
console.log(person1.__proto__); //{ name: 'lhf', age: 24, getName: [Function (anonymous)] }

使用Object.getPrototypeOf() 获取这个实例的原型;

var person1 = new Person();
console.log(Person.prototype) //{ name: 'lhf', age: 24, getName: [Function (anonymous)] }
console.log(Object.getPrototypeOf(person1) === Person.prototype); //true

当读取到某个实例的属性时,先从对象本身开始查找,如果实例中找不到,则继续搜索指针指向的原型对象;使用delete操作符可以完全删除实例属性。

var person1 = new Person();
console.log(person1.name); //lhf ,在原型上搜索的结果
person1.name = 'zuzu';
console.log(person1.name); // zuzu,在实例上已经搜索到属性的值,不会往原型上搜索
delete person1.name;
console.log(person1.name); //lhf

hasOwnProperty()可以检测一个实例属性是否存在某个实例中,而非原型;  property :属性

var person1 = new Person();
console.log(person1.hasOwnProperty("name"));  //false, 此时访问的是原型属性
person1.name = 'zuzu';
console.log(person1.hasOwnProperty("name"));  //true

 in操作符、for-in可以同时访问实例属性和原型属性

var person1 = new Person();
console.log('name' in person1);  //true
person1.name = 'zuzu';
console.log("name" in person1);  //true

ES6, 类的内部所有定义的方法,都是不可枚举的(enumerable = false);

Object.getOwnPropertyNames()

  • Person.prototype:适用于ES5、ES6的类 (Person.prototype也可以看最一个对象,object);获取原型的所有属性;无论是否可枚举,但不适用于私有属性;
  • object: 对于普通的实例对象,只能获取实例属性

Object.keys()

  • Person.prototype:获取ES5原型属性key( ES5的原型是可以枚举的,ES6类的内部所有定义的方法,都是不可枚举的);
  • object:获取实例可枚举的自身属性
function Person(name) {
  this.name = name;
}
Person.prototype.age = 24;
Person.prototype.getName = function(){
  console.log(this.name);
}
//输出: [ 'age', 'getName']
console.log(Object.keys(Person.prototype));
//输出: [ 'constructor', 'age', 'getName' ]
console.log(Object.getOwnPropertyNames(Person.prototype));

//ES6
class Point {
  constructor(x, y) {
  }
  toString() {
  }
}
// [],ES6的方法都在原型上,是不可枚举的
console.log(Object.keys(Point.prototype)); 
//[ 'constructor', 'toString' ]
console.log(Object.getOwnPropertyNames(Point.prototype));

​
var my_obj = Object.create({}, {
    getFoo: {
      value: function() { return this.foo; },
      enumerable: false
    }
  });
  my_obj.foo = 1;
  
  console.log(Object.getOwnPropertyNames(my_obj).sort()); // ["foo", "getFoo"]

  console.log(Object.keys(my_obj)); //[ 'foo' ]

  for (let i in my_obj){  //foo
      console.log(i);
  }

ES5,下面是原型的另一种赋值方法(Person函数同上),唯一不同的是,constructor不再指向Person了,因为下面写法本质上是重写了prototype,constructor已经无法确定对象的类型了,指向的是Object

Person.prototype = {
  age:24,
  getName:function(){
    console.log(this.name);
  }
}
//[ 'age', 'getName' ]
console.log(Object.getOwnPropertyNames(Person.prototype));

let person1 = new Person();
console.log(person1.constructor == Person);  //false
console.log(person1.constructor == Object);  //true

原生对象(Object、String、Array等)的都在其构造函数的原型上定义了方法,通过原生对象的原型修改或添加一些方法

console.log(typeof Array.prototype.sort);  //function
console.log(typeof String.prototype.substring);  //function

原型链

JS 原型链,原型链的顶端是什么?

Object.prototype

Object 的原型是什么?

console.log(Object.getOwnPropertyNames(Object.prototype));
/*
[
  'constructor',
  'hasOwnProperty',
  'toLocaleString',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'toString',
  'valueOf',
  '__lookupGetter__',
  '__lookupSetter__',
  '__defineGetter__',
  '__defineSetter__',
  '__proto__'
]
*/

继承

1.原型链继承

原型链是作为实现继承的主要方法

  • 下面代码实现了XiaoMing继承Person,通过创建Person实例,并将该实例赋值给XiaoMing.prototype实现的,实现的本质是重写原型对象(所以constructor指针消失)。
  • XiaoMing原型指向了Person原型,并且也拥有自己的原型方法(getName),实现了对Peron属性与方法的继承。
  • 关于age属性为什么会出现在XiaoMing原型中,因为age是Person的实例属性,而XiaoMing.prototype又指向Person的实例(包含age),所以age存在于XiaoMing的原型中。
function Person(){
  this.age=[0, 1, 2];
}
Person.prototype.getAge = function(){
  return this.age;
}
//Person原型 [ 'constructor', 'getAge' ]
console.log(Object.getOwnPropertyNames(Person.prototype)); 

function XiaoMing(){
  this.name='xiaoming';
}
//继承了Person,构造函数指针指向了Person的原型对象
XiaoMing.prototype = new Person();
XiaoMing.prototype.getName =  function(){
  return this.name;
}
//XiaoMing原型 [ 'age', 'getName' ]
console.log(Object.getOwnPropertyNames(XiaoMing.prototype));
//XiaoMing.prototype.constructor也指向Person
console.log(XiaoMing.prototype.constructor);  //Function: Person

var a = new XiaoMing();
console.log(a.getAge());

 默认的继承

所有的引用类型都默认继承了Object,而这个继承也是通过原型链实现的,所有函数的默认原型都是Object的实例。因此默认原型搜会包含一个内部指针,指向Object.prototype.

确定原型与实例的关系

instanceof,A instanceof B == true,说明A是B的实例,B可能是直接对象或继承对象

isPrototypeof, B.prototype.isPrototypeof(A) == true, 同上

原型链的问题

  • 从前面介绍,我们知道实例会共享原型的引用类型的值(可以参考原型模式),当一个函数继承了另一个函数,如上面的例子,age实例属性,相当于它是XiaoMing原型的引用类型, 它的值会被XiaoMing的所有实例共享。
  • 在创建子类型实例时,无法向超类型的构造函数传递参数

2.借用构造函数(经典继承 | 伪造函数)

主要思想:在子类型的构造函数内部,调用超类型构造函数,一般使用call()和apply()方法。

优点:子类可向超类传递参数

缺点:子类不能继承超类的原型

function Parent() {
  this.age = [0, 1, 2, 10];
}
Parent.prototype.name = "hha";
function Son() {
  Parent.call(this);
}

var kk = new Son();
for (let i in kk) {   //只输出 age,说明超类中的原型未被继承
  console.log(i);
}
console.log(Object.getPrototypeOf(kk));  //{}

3.组合继承

主要思想:使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承

两种方法的继承!!!

function Parent() {
  this.age = [0, 1, 2, 10];
}
Parent.prototype.name = "hha";
function Son() {
  //继承Parent的实例属性
  Parent.call(this);
}
//继承Person的原型属性及方法
Son.prototype = new Parent();

var kk = new Son();
for (let i in kk) {   //输出 age、name
  console.log(i);
}
console.log(Object.getPrototypeOf(kk));  //Person { age: [ 0, 1, 2, 10 ] }

这样就达到了,让两个实例,既有自己的实例属性(age属性),又有公共的原型属性

var kk = new Man();
var uu = new Man();
kk.age.push(100);
console.log(kk.age);  //[ 0, 1, 2, 10, 100 ]
console.log(uu.age);  //[ 0, 1, 2, 10 ]

原型链的继承思想:

每个实例对象都有(指向)自己的原型,而每个实例对象可以作为子类的原型对象,这样就实现了继承。当创建子类的实例对象时,实例对象就有了自己的实例属性(age属性),又有公共的原型属性

实例对象可以作为子类的原型对象
Son.prototype = new Parent();
相当于重写了子类的原型,所以子类的原型对象的constructor指向的是Parent
console.log(Son.prototype.__proto__.constructor == Parent ) //true
console.log(Son.prototype.constructor == Parent )

应用:vue的全局挂载

4.原型式继承

主要思想:借助原型,可以基于已有的对象创建新对象。

在object函数内部,先创建一个临时的构造函数,将传入的对象作为这个构造函数的原型,返回这个临时构造函数的实例。

function object(o){
  function F(){}
  F.prototype = o;
  return new F();
}

var person = {
  name: 'haha',
  age: [0, 1, 5]
}

var person1 = object(person);
person1.age.push(11);
var person2 = object(person);
console.log(person2.age);  //[ 0, 1, 5, 11 ]

ES5用Object.create()规范了原型式继承 ,Object.create() = object() ,第一个参数是传入的对象,第二个参数的每个属性都是通过自己的描述定义的

var person = {
  name: 'haha',
  age: [0, 1, 5]
}

var person1 = Object.create(person, {
  name: {
    value: "zuzu"
  }
});
console.log(person1.name);  //zuzu

5.寄生式继承

与寄生构造函数模式类似,即创建一个仅用于封装继承过程的函数

class(ES6)

创建实例与es5完全一样,通过new创建

class Point {
    // constructor 构造方法
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
    // 添加方法,省略了function
    toString() {
      return '(' + this.x + ', ' + this.y + ')';
    }
  }

obj = new Point(1, 2);
console.log(obj.toString()); // (1, 2)

constructor 方法

是类的默认方法,通过new命令创建实例时,自动添加该方法,constructor方法默认返回该实例对象(this),构造方法里的属性都是实例属性,即是每个实例所特有的,不共享。

下面的代码表明,类的数据类型就是函数,类本身就指向构造函数(constructor)

class Point {
  // constructor 构造方法
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}

console.log(typeof(Point));   //function
console.log(Point === Point.prototype.constructor);  //true

prototype属性

在 ES6 的“类”上面继续存在,事实上,类的所有外部方法都定义在prototype原型上,如下面的toString,且都是不可枚举的

class Point {
  constructor() {
  }
  toString() {
  }
}

// 等同于
Point.prototype = {
  constructor() {},
  toString() {}
};

Object.assign

可以方便的一次性添加多个类函数

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
}
//一次性添加多个函数
Object.assign(Point.prototype, {
  add(){
    return this.x+this.y;
  },
  sub(){
    return this.x-this.y
  }
});

P = new Point(1, 2);
console.log(P.add());  //3
console.log(P.sub());  //-1

取值函数(getter)与存值函数(setter)

与 ES5 一样,在“类”的内部可以使用getset关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为

class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return "getter";
  }
  set prop(value) {
    console.log("setter: " + value);
  }
}

let inst = new MyClass();

inst.prop = 123;
// setter: 123

console.log(inst.prop);
// 'getter

class的其他定义方式

Point类名只在类的内部可用,如果内部没用到,可以省略类名Point;创建对象还需要用MyPoint

const MyPoint = class Point{
  constructor(name){
    this.name = name;
  }
   getName(){
     console.log(Point.name) // Point
     return this.name
   }
}

var obj = new MyPoint('lhf');
console.log(obj.getName());  //lhf

 可以写出立即执行的 Class

 注意点

类需要先定义,再调用,子类需要写在父类的后面

类中this的指向

方法中的this,默认指向类的实例

静态方法

类的内部函数加上static就是静态方法,代表着不会被实例继承,只有通过类名调用;

如果静态方法中包含this,这个this指向的是类而不是实例;

子类可以继承父类的静态方法,可直接被子类调用

类的实例属性

1.定义在constructor函数的this上面; 1.直接定义在类的最上面,不用添加this

类的私有方法

方法一:_+函数名,声明为私有方法仅供内部使用,但是在类的外部还是可以调用的

方法二:把方法放到类的外部,在类的内部调用函数,达到私有方法的目的

方法三:利用Symbol值的唯一性

//方法一
class Widget {
  foo (name) {
    this._setName(name);
  }
  _setName(name) {
    return this.name = name;
  }
}

//方法二
class Widget {
  foo (name) {
    setName.call(this, name);
  }
}
function setName(name) {
  return this.name = name;
}

let obj = new Widget();
obj.foo('haha');
console.log(obj.name); //haha

类的私有属性

#+属性名,即是私有属性;  #+方法名,即是私有方法;外部调用会出错

class Counter{
  #count = 0;
  increment(){
    this.#count++;
  }
  print(){
    console.log(this.#count);
  }
  #log(){
    console.log(this.#count);
  }
}

const counter = new Counter();
counter.increment(); 
counter.print();  //1
counter.log();  //报错

判断实力是否存在某个私有属性,可以用in运算符在类的内部判断

new.target属性

new是构造函数生成实例的命令,ES6为new添加了一个属性new.target, 返回类名;子类继承父类时,new.target会返回子类,可以利用这个特点,判断是否为继承后的类。

继承(ES6)

1.extent继承

ES5继承的实质(构造函数方式):先创建子类的实例对象this,再将父方法添加到this上面 Person.call(this);

ES6继承的实质:先创建父类的实例对象this(调用super()),再在子类的构造函数中修改this

有调用super之后,才可以使用this关键字

class Person{
  constructor(){
    this.age = [1, 10];
  }
}
class Man extends Person{
  constructor(name){
    super();  //调用父类
    this.name = name;
  }
  getName(){
    return this.name;
  }
}

let kk = new Man('kk');
console.log(kk.getName());

2.Object.getPrototypeOf()

获取子类的父类

3.super()

子类继承父类时使用super(), 代表调用父类的构造函数,但是返回的是子类B的实例,即super内部的this指的是B的实例

class A {
  constructor() {
    console.log(new.target.name);
  }
}
class B extends A {
  constructor() {
    super();
  }
}
new A() // A
new B() // B

super作为对象时,在普通函数中,指向父类的原型。所以super.p()就相当于A.prototype.p(),所以super对象不能调用父类实例上的方法或属性。在静态方法中,指向父类

class A {
  p() {
    return 2;
  }
}

class B extends A {
  constructor() {
    super();
    console.log(super.p()); // 2
  }
}

let b = new B();

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例;

在子类的静态方法中通过super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例

class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}

class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  m() {
    super.print();  //this指向当前子类实例
  }
}
let b = new B();
b.m() // 2

class的两条继承链

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/125279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTF之密码学题目-classical coding

CTF系列文章 第一篇 CTF之密码学题目-classical && coding 文章目录CTF系列文章前言一、题目是什么?二、解题步骤1.下载文件,解压2.解码Unicode3.ASCII码解码4.BrainFunk解码5.莫斯码解码6.字频解密总结前言 在CTF比赛中,有关密码学…

Memtiter-benchmark源码解析2--shared_connection

shard_connection.h class shad_connection private members Line 161 行 bufferevent* m_bev;重要的bufferevent_event important methods setup_event shard_connection.cpp bufferevent_setcb 设置了 m_bev 的读事件的函数回调,没有设置写事件的函…

如何策划一场银行校招线上笔试?

策划一场银行校园招聘线上笔试,只需要4步。 牛客基于服务的上千家企业现状发现,银行业大多数企业在校园招聘的笔试环节会面临这些核心问题: 缺乏出题专业度:大多数企业出题者为业务部门员工,技能水平不一&#xff0c…

Educational Codeforces Round 97 (Rated for Div. 2) D. Minimal Height Tree

Problem - D - Codeforces 翻译: Monocarp有一棵树,它由𝑛个顶点组成,并以顶点1为根。他决定研究BFS(宽度优先搜索),所以他在他的树上运行BFS,从根开始。BFS可以用下面的伪代码描述: A [] #处理顶点的顺序…

欧几里得空间

文章目录1 欧几里得范数2 距离3 标准内积4 柯西-施瓦茨不等式5 正交6 叉乘7 平行四边形法则8 欧几里得运动线性空间里最重要的就是欧几里得空间了,这是线性代数学习绕不过去的槛。欧几里得空间,学习起来我觉得吧,主要是三个点:内积…

Golang面试宝典——Go语言实现排序算法之快速排序

关于Golang面试宝典 最近几年,Go的热度持续飙升,国内外很多大公司都在大规模的使用Go。Google是Go语言诞生的地方,其他公司如Facebook、腾讯、阿里、字节跳动、百度、京东、小米等都在拥抱和转向Go。Go语言的开源项目也非常多,如…

无人驾驶(四)---远程桌面控制工具: NoMachine踩坑记录

NoMachine for mac是一款免费的远程桌面访问工具,这款软件的连接到远程桌面后延迟可以非常低,NX协议在高延迟低带宽的链路上提供了近乎本地速度的响应能力,打破空间和时间的障碍,让您的桌面环游世界。 1.环境配置 服务端&#x…

西门子PLC各类通信协议差异对比

西门子PLC有4大类,几十个型号类型,PLC不同所支持的通讯协议也不相同。 S7-200系列支持的协议有:PPI、MPI、PROFIBUS、以太网、S7协议、AS-INTERFACE、USS、MODBUS、自由口。 S7-300\400系列支持的协议有:MPI、PROFIBUS、ETHERNE…

陌陌综合案例

注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase Hive Flume等…

【python3】10.python高阶内容:装饰器

10.python高阶内容:装饰器 2022.12.28 装饰器装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。参数可以是函数,返回值也可以是函数。 10.1 形式 def decorator(fn):def wrapper(name):print(name&…

【Linux进程】进程的基本概念,fork的使用,各种状态的含义,孤儿和僵尸进程的含义

目录 1.进程的基本概念 2.描述进程-PCB 3.fork创建子进程 4.各种状态对应的含义及进程大概的运行原理 5.僵尸进程 ​6.孤儿进程 7.进程的优先级 1.进程的基本概念 2.描述进程-PCB PCB概念:进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集…

ChatGPT注册教程

ChatGPT是最近很火的AI智能对话聊天软件。我们是能够去用来进行更加自由的智能内容讨论和聊天。有的小伙伴还不知道怎么注册。 官方地址:chat.openai.com/chat 注册步骤 1、进入官网后,点击注册按钮。 2、点击创建账号。 3、输入自己的邮箱账号。 4、…

整合Kafka

Main Concepts 一些服务器形成了存储层,被称为broker,其他服务器运行kafka连接去不断地导入和导出数据作为事件流,将kafka和关系型数据库等存在的系统集成。 Servers: Kafka is run as a cluster of one or more servers that can span mult…

高手不用Redis内存数据库一

不是说Redis不好,不用Redis用别的(比如:Memcached 2、VoltDB 3、MongoDB 4、Hazelcast 5、Aerospike) No! No! No!!! Redis 很好,我不拦着您用…… 而是说,我们的水平更高了以后,您一定会感受到 内存数据库 不够用、不够灵活、不…

JavaScript基础篇2之日期时间函数

一、计算机中时间字母表示的预知识储备: G(age,时代年龄等意思):时代标志,如AD(Anno Domini公元)、BC(Before Christ公元前)。 y(year&#xff…

zabbix安装使用

1.1 Zabbix概述 Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix使用灵活的通知机制,允许用户为几乎任何事件配置基于邮件的告警。这样可以快速反馈服务器的问题。基于已存储的数据,Zabbix提供了出色的报告和数据可视化功能。…

基于python的turtle实现圣诞树的绘制

文章目录一、前言二、基于turtle实现绘制圣诞树三、效果展示四、实现步骤代码实现分步骤1. 导入库2. 配置圣诞树高度等信息3. 定义函数get_color()可获取随机颜色4. 定义函数snow() 绘制一朵雪花5. 定义函数name()可随机写一些文字6. 定义函数koc() 绘制星星7.定义函数tree()绘…

Qt中调用thrift

thrift是一个Apache公司开源的一款RPC(Remote Procedure Call)框架,让不同语言构建的服务可以做到远程调用无缝对接。 thrift库分两部分: libthrift - 核心库文件,需要依赖OpenSSL、boost libthriftnb - 包含thrift非阻…

内网穿透基本使用

内网穿透基本使用 文章目录内网穿透基本使用前言一、内网穿透二、工具1.FRP2.LCX3.NPS4.Sunny-Ngork三、Sunny-ngork使用四、Frp内网穿透代理1.一层代理2.二层代理总结前言 之前零零碎碎接触过不少关于内网渗透测试、内网穿透的知识,但是不得不说渗透测试很吃基础、…

初学Java web(十一)AjaxAxiosJSON

Ajax&Axios&JSON 概念:AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML AJAX作用:1.与服务器进行数据交换:通过AJAX可以给服务器发送请求,并获取服务器响应的数据 使用了AJAX和服务器进行通信,就可以使用HTMLAJAX来替…