【JavaScript】原型链/作用域/this指针/闭包

1.原型链

参考资料:Annotated ES5

ECMAScript起初并不支持如C++、Smalltalk 或 Java 中“类”的形式创建对象,而是通过字面量表示法或者构造函数创建对象。每个构造函数都是一个具有名为“prototype”的属性的函数,该属性用于实现基于原型的继承和共享属性。通过在new表达式中使用构造函数来创建对象;例如,new Date(2009,11) 创建一个新的 Date 对象。

继承:指的是将特征从父级传递给子级,以便新的代码段可以重用并基于现有代码的特性进行构建。

原型对象:由构造函数创建的每个对象都对其构造函数的“prototype”属性的值有一个隐式引用(称为该对象的原型对象),即在下列代码中,称“Animal.prototype”为“animal的原型对象”,“Animal.prototype”本身也是个对象。

/*构造函数*/
function Animal(name,weight){
    this.name = name
    this.weight = weight
}
/*在new表达式中使用构造函数创建的对象*/
const animal = new Animal('米粒',10)

console.log('animal的原型:',Animal.prototype)

原型链:原型对象本身也有自己的原型,以此类推,直到到达一个原型为 null 的对象(null 没有原型而作为引用链的终点)。我们称这一条完整的隐式引用链为原型链(prototype chain)。原型链的作用是为了实现继承和共享属性。

__proto__:对象的内置属性(非标准的属性,但已经被绝大部分Javascript引擎实现,对应于ECMAScript中的[[prototype]],ECMAScript标准的获取对象原型的API是Object.getPrototypeOf() ),用于指向该对象的原型对象prototype,即:

/*构造函数*/
function Animal(name,weight){
    this.name = name
    this.weight = weight
}
/*在new表达式中使用构造函数创建的对象*/
const animal = new Animal('米粒',10)

console.log('animal的原型:',Animal.prototype)
console.log('animal的原型:',animal.__proto__)
console.log('animal.__proto__===Animal.prototype:',animal.__proto__===Animal.prototype)
/*通过Object.getPrototypeOf()规范地获取animal的原型*/
console.log('animal的原型:',Object.getPrototypeOf(animal))

constructor: 原型对象prototype上都有个预定义的constructor属性,用来引用它的函数对象。这是种循环引用的目的是允许人们从任何实例访问原始构造函数。

/*构造函数*/
function Animal(name,weight){
    this.name = name
    this.weight = weight
}
/*在new表达式中使用构造函数创建的对象*/
const animal = new Animal('米粒',10)
// Animal.prototype.constructor === Animal: true
console.log('Animal.prototype.constructor === Animal:',Animal.prototype.constructor === Animal)

注意要点:
(1)构造函数是一个函数对象,所以其原型是Function.prototype。
(2)原型对象是一个对象,所以其原型是Object.prototype。
(3)Object.prototype.__proto__ 指向 null,null是原型链的终点。
(4)尝试访问对象的属性时,不仅要在对象上查找该属性,还要在对象的原型prototype、原型的原型等上查找该属性,直到找到具有匹配名称的属性或到达原型链的末尾。

完整原型链示例图:(其中Animal、Object、Function是构造函数)

2.作用域

参考文档:ECMA-262-5 in detail. Chapter 3.1. Lexical environments: Common Theory. – Dmitry Soshnikov

作用域(Scope):一个封闭的上下文,用于管理程序不同部分的变量的可见性和可访问性。我们也可以说,作用域是一个逻辑边界,其中的变量(或表达式)有其独特的含义。例如,全局变量、局部变量等,通常反映变量生存期(或范围)的逻辑范围。

作用域属性:嵌套、变量解析方式(静态作用域和动态作用域)。

作用域链:由于作用域可以逐层嵌套,所以各层作用域组成了一个逻辑链,我们称其为作用域链。当访问某个变量时,js引擎会从当前作用域开始在包裹当前作用域的父级作用域中查找,若未找到,则再向上查找父级作用域,以此类推。从执行上下文角度看,作用域链是由环境记录(EnvironmentRecord)中的外部环境引用属性(OuterEnv)串联而成。

块级作用域: ES6 之前, ECMAScript 不支持块级作用域:

var x = 10;
 
if (true) {
  var x = 20;
  console.log(x); // 20
}
 
console.log(x); // 20

可以通过立即调用函数表达式IIFE实现:

var x = 10;
 
if (true) {
  (function (x) {
    console.log(x); // 20
  })(20);
}
 
console.log(x); // 10

通过函数作用域隔离变量,实现了个性化块级作用域效果,这也是ES6之前js模块化开发的依据。直到ES6 中标准化了 let 关键字,创建块范围的变量就变得方便多了:

let x = 10;
 
if (true) {
  let x = 20;
  console.log(x); // 20
}
 
console.log(x); // 10

静态作用域:亦称词法作用域。在静态作用域中,标识符指向其最近的词法环境,变量的作用域在代码编写时就确定的,并且在程序执行期间不会改变。具有以下特点:

  1. 定义位置决定作用域:变量的可访问范围由其定义的位置决定。
  2. 函数内部的变量:只能在该函数内部访问和使用。
  3. 块级作用域:可能存在块级别的作用域,限制变量的可见性。
  4. 稳定性:在运行时作用域不会改变。

例如,下列例子中,变量 x 在全局作用域中进行了词法定义——这意味着在运行时它也在全局作用域中进行解析,即解析为10。而对于 y 这个变量,我们定义了两次。但正如前面所说,总是考虑包含该变量的最近的词法作用域。自身作用域具有最高优先级并被首先考虑。因此,在 bar 函数的情况下,y 变量被解析为 30。bar 函数的本地变量 y 被称为遮蔽了全局作用域中同名的变量 y。然而,在 foo 函数的情况下,同名的 y 被解析为 20——即使它是在包含另一个 y 的 bar 函数内部被调用的。也就是说,标识符的解析独立于调用者的环境(在这种情况下,bar 是 foo 的调用者,而 foo 是被调用者)。同样,这是因为在定义 foo 函数时,具有 y 名称的最近的词法上下文——是全局上下文。

var x = 10;
var y = 20;
 
function foo() {
  console.log(x, y);
}
 
foo(); // 10, 20
 
function bar() {
  var y = 30;
  console.log(x, y); // 10, 30
  foo(); // 10, 20
}
 
bar();

动态作用域:在程序运行时才能确定变量的作用域。在该作用域中,变量不是在词法环境中解析,而是在动态形成的全局变量堆栈环境中解析。每次遇到变量声明,只是将变量的名称放在堆栈上。变量的作用域(生命周期)结束后,变量将从堆栈中移除(弹出)。这意味着,对于单个函数,我们可能有相同变量名的无限解析方式——这取决于调用该函数的上下文。

Javascript使用的是静态作用域。虽然ECMAScript中的with指令和eval指令具有动态效果,但不像标准动态作用域定义中那样涉及全局变量堆栈,这两个指令对静态作用域起到的效果可以称之为:“Runtime scope augmentation”(运行时作用域增强)

可执行代码:在ECMAScript 中有三种可执行代码:
(1)全局代码global code:是被视为 ECMAScript 程序的源文本,在全局作用域中执行的代码。
(2)Eval 代码eval code:通过 eval 函数动态执行的字符串形式的代码。提供给内置 eval 函数的源文本。更准确地说,如果内置 eval 函数的参数是 String,则将其视为 ECMAScript 程序。特定调用的 eval 代码 eval 是该程序的全局代码部分。
(3)函数代码function code:作为 FunctionBody 的一部分进行分析的源文本,包含在函数定义内部的代码。

全局代码在程序的任何地方都可以访问和执行。函数体代码只有在函数被调用时才会执行。eval 函数可以动态地解析和执行字符串中的代码,但由于其安全性和性能方面的考虑,在实际开发中应谨慎使用。

每种可执行代码在执行前,会经js引擎编译并创建对应的执行上下文。全局代码在全局上下文中执行,函数代码在函数上下文中执行,Eval代码在Eval上下文中执行。每一个js文件只有一个全局上下文。

执行上下文:包含跟踪其关联代码的执行进度所需的任何状态。每个执行上下文均包含三个状态组件:
(1)词法环境(LexicalEnvironment):用于实现作用域。包含两个组成部分:

  • 环境记录(EnvironmentRecord):将变量名映射到变量值(类似于Map)。作用域变量的实际存储空间。记录中的「名称-值」条目称为绑定。
  • 对外部环境的引用(OuterEnv):当前可以访问的外部词法环境,是一个抽象类,有3个具体的子类:
    A.声明式环境记录:又派生出函数环境记录和module环境记录。
    B.对象环境记录;
    C.全局环境记录。

    因此,可以认为存在三种作用域:
    A.声明式作用域:可以通过 var/const/let/class/module/import/function生成。ES6块级作用域是函数作用域的子级。
    B.对象作用域:使用with关键字指定代码块的作用域范围:
    function test(){
        let ob = { name:'javascript' };
        // 利用with扩展了作用域
        with(ob){
            console.log(`Hello ${name}`)
        }
    }
    
    test(); // Hello javascript

    C.全局作用域:最外层的作用域。Outer Env为null。通过声明式环境记录(使用内部对象存储变量)和对象环境记录(将变量存储在全局对象中)来管理变量。

(2)变量环境(VariableEnvironment):本质是一个对象,记录此执行上下文中由 VariableStatements 和 FunctionDeclarations 定义的变量和函数(即var和function声明的标识符)。
(3)this绑定(ThisBinding):与此执行上下文关联的 ECMAScript 代码中 this 的关键字关联的值。

ES6中执行到代码块时,如果代码块中有 let 或者 const 声明的变量,针对变量的查询路径为: 1. 词法环境 2. 变量环境 3. OuterEnv对象(上一层作用域继续先1后2)

工作过程:当控制转移到 ECMAScript 可执行代码时,控制正在进入执行上下文。活动执行上下文在逻辑上形成一个堆栈。此逻辑堆栈上的顶级执行上下文是正在运行的执行上下文。每当将控制从与当前正在运行的执行上下文关联的可执行代码传输到与该执行上下文无关的可执行代码时,都会创建一个新的执行上下文。新创建的执行上下文被推送到堆栈上,并成为正在运行的执行上下文。

作用域和执行上下文的关系:作用域是执行上下文有权访问的一组有限的变量或对象,同一个执行上下文上可能存在多个作用域,每个执行上下文均有自己的作用域。

执行上下文堆栈(ECS:Execution context Stack)ECS:ECMAScript 用来管理函数执行的调用堆栈模型称为执行上下文堆栈。工作过程如下:

  • 首先创建全局执行上下文, 压入栈底
  • 每当调用一个函数时,创建函数的函数执行上下文。并且压入栈顶
  • 当函数执行完成后,会从执行上下文栈中弹出,js引擎继续执栈顶的函数。

变量提升:js代码在执行前还有一个编译的过程,在编译过程中,var变量和function函数部分会被js引擎放入到对应上下文的变量环境中,并且变量会被默认设置为undefined。在执行阶段,js引擎才会在变量环境中查找到声明的变量和函数。在程序员角度看来,就出现了变量在声明前就可以访问,并且函数在定义之前便可调用的现象。我们称该现象为变量提升。
需要注意的是,var变量只有创建和初始化被提升,赋值并没有被提升;而function的创建、初始化和赋值均会被提升。所以在变量的声明之前访问,该变量的值是undefined,而函数则可以在声明之前正常调用。

暂时性死区:ES6中引入了let、const关键字,解决了变量提升问题,使得js支持块级作用域。严格意义上,letconst没有解决变量提升问题,当js代码被编译时,letconst变量代码会被存放在词法环境中。此时letconst变量已经被提升到了作用域顶部,但是只是声明被提升,初始化和赋值并没有被提升,如果在赋值代码行之前去读写该变量,便会报错。我们将这种从作用域开始到赋值变量代码之前暂时无法读写对应变量的区域称为“暂时性死区”

头等函数( first-class functions ):可以以变量使用的函数,如:将函数作为另一个函数的参数,将函数赋值给变量,将函数作为另一个函数的返回值。Javascript就是具有头等函数的语言。

高阶函数:满足两个条件之一的函数:接受函数作为参数传递的函数;返回一个另一个函数的函数。

回调函数:被当做参数传递给另一个函数的函数。

3.this指针

        this是一个的关键字,用于指向一段代码(如函数的主体)应该运行的上下文。JavaScript 中“this”的值取决于函数是如何被调用的(即运行时绑定),而不是它是如何被定义的。
        当一个普通函数作为对象的方法被调用(obj.method())时,“this”指向该对象。
        当作为一个独立的函数被调用(没有附着在任何一个对象上:func())时,“this”通常指的是全局对象(在非严格模式下)或undefined(在严格模式下)。Function.prototype.bind()方法可以创建一个“this”绑定不会改变的函数,并且方法 apply()和 call()也可以为特定的调用设置“this”值。
        箭头函数在处理 this 时有所不同:它们在定义时从父作用域继承 this。这种行为使箭头函数对于回调和保留上下文特别有用。然而,箭头函数没有自己的 this 绑定。因此,它们的 this 值不能通过 bind()、apply() 或 call() 方法进行设置。

在非严格模式下, this 始终指向一个对象。在严格模式下,可以指向任何值。this的取值由其出现的上下文环境决定,具体情况如下:

(1)函数上下文

在函数内部,this 的值取决于函数如何被调用。可以将 this 看作是函数的一个隐藏参数(就像函数定义中声明的普通参数一样),this 是在函数体被执行时创建的绑定。

对于典型的函数,this 的值是函数被访问的对象。换句话说,如果函数调用的形式是 obj.f(),那么 this 就指向 obj

严格模式下:
如果函数在没有被任何东西访问的情况下被调用,this 将是 undefined。

非严格模式下:
如果一个函数被调用时 this 被设置为 undefined 或 null,则this 会被替换为globalThis;
如果函数被调用时 this 被设置为一个原始值,this 会被替换为原始值的包装对象。

function bar() {
  console.log(Object.prototype.toString.call(this));
}

bar.call(7); // [object Number]
bar.call("foo"); // [object String]
bar.call(undefined); // [object Window]

(2)全局上下文

在脚本的顶层,无论是否在严格模式下,this 会指向globalThis。如果源代码放在 HTML 的<script>元素内并作为脚本执行,则this === window

如果源代码作为模块加载(对于 HTML,这意味着在 <script> 标签中添加 type="module"),在顶层,this 总是 undefined

如果源代码使用eval()执行,this 与直接调用eval() 的闭合上下文相同,或者与间接调用 eval 的 globalThis(就像它在单独的全局脚本中运行一样)相同。

bind():

调用f.bind(someObj)会创建一个新函数,这个新函数具有与 f 相同的函数体和作用域,但 this 的值永久绑定(一旦绑定,后续再次绑定到其他对象的操作将会被忽略,绑定不生效但入参生效)到 bind 的第一个参数,无论函数如何被调用。调用绑定函数通常会执行其所包装的函数,也称为目标函数(target function)。绑定函数将绑定时传入的参数(包括 this 的值和前几个参数)提前存储为其内部状态,而不是等到实际调用时才传入。

"use strict"; // 防止 `this` 被封装到到包装对象中

function log(...args) {
  console.log(this, ...args);
}
const boundLog = log.bind("this value", 1, 2);
const boundLog2 = boundLog.bind("new this value", 3, 4);
boundLog2(5, 6); // "this value", 1, 2, 3, 4, 5, 6

用法:其中arg1,arg2......可选,

bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* …, */ argN)

手写实现

Function.prototype.myBind = function () {
    const _this= this
    const args = Array.prototype.slice.call(arguments)
    const newThis = args.shift()
    return function () {
      return _this.apply(newThis, args)
    }
}

apply():

        通常情况下,在调用函数时,函数内部的this的值是访问该函数的对象。使用 apply(),你可以在调用现有函数时将任意值分配给 this,而无需先将函数作为属性附加到对象上。
        可以使用任何类数组对象作为第二个参数。实际上,这意味着它需要具有 length 属性,并且整数(“索引”)属性的范围在 (0..length - 1) 之间。像 { 'length': 2, '0': 'eat', '1': 'bananas' }这样的对象或['a','b']这样的数组甚至直接使用arguments,当然还可以使用剩余参数或者展开运算符。
        一般而言,fn.apply(null, args) 等同于使用参数展开语法的 fn(...args),只是在前者的情况下,args 期望是类数组对象,而在后者的情况下,args 期望是可迭代对象。

用法如下:

apply(thisArg)
apply(thisArg, argsArray)

手写实现

Function.prototype.myApply = function (context, args) {
    context = context || window
    args = [...args]
    const fn = Symbol()
    context[fn] = this
    const result = context[fn](...args)
    delete context[fn]
    return result
}

call():

功能与apply一致,只不过传参不同,函数的参数以列表的形式逐个传递给 call()的。

function greet() {
  console.log(this.animal, "的睡眠时间一般在", this.sleepDuration, "之间");
}

const obj = {
  animal: "猫",
  sleepDuration: "12 到 16 小时",
};

greet.call(obj); // 猫 的睡眠时间一般在 12 到 16 小时 之间

用法:

call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, arg2)
call(thisArg, arg1, arg2, /* …, */ argN)

 如果省略第一个 thisArg 参数,则默认为 undefined。在非严格模式下,this 值将被替换为全局对象globalThis。

 手写实现

Function.prototype.myCall = function (context) {
    context = context || window
    const arg = [...arguments].slice(1)
    const fn = Symbol()
    context[fn] = this
    const result = context[fn](...arg)
    delete context[fn]
    return result
}

bind()、apply()、bind()三者的异同

(1)相同点 
        bind、call、apply都能为函数内部的this分配指定值。 第一个参数均为this的目标值。均可以利用后续参数向目标函数传参。
(2)不同点
        call和bind传参相同,均是以此传入多个参数。apply只有两个参数,第二个参数为数组或类数组。call和apply均是直接调用目标函数,而bind方法不会立即调用函数,而是返回一个修改this后的新函数。
(3)使用场景 
        call函数的使用多用于类的继承。
        apply函数可配合Math.max()用于计算数组最大值等。
        bind函数可用于函数内部有定时器,改变定时器内部的this指向。

4.闭包

概念:在 JS 中,根据词法作用域的规则,内部函数总是可以访问其外部函数中声明的变量。当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了。但是内部函数引用外部函数的变量依然保存在内存中,就把这些变量的集合称为闭包。简单而言,闭包是一个函数,其有权访问其词法作用域内部的变量即使该函数在词法作用域外部被调用。

柯里化

在JavaScript中,函数柯里化是一种将多个参数的函数转变为一系列接受单一参数的函数的过程。这种转变过程可通过闭包和递归的方式实现。利用闭包,可以形成一个不销毁的私有作用域,把预先处理的内容都存在这个不销毁的作用域里面。

function multiply(a) {
  return function executeMultiply(b) {
    return a * b;
  }
}
const double = multiply(2);
double(3); // => 6
double(5); // => 10
const triple = multiply(3);
triple(4); // => 12

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【氮化镓】在轨实验研究辐射对GaN器件的影响

【Pioneering evaluation of GaN transistors in geostationary satellites】 摘要&#xff1a; 这篇论文介绍了一项为期6年的空间实验结果&#xff0c;该实验研究了在地球静止轨道上辐射对氮化镓&#xff08;GaN&#xff09;电子元件的影响。实验使用了四个GaN晶体管&#xf…

H3C防火墙RBM对接交换机M-LAG典型配置

FW配置&#xff1a;FW1与FW2采用RBM组网&#xff0c;M-LAG Border的跨设备二层聚合口与RBM FW设备的设备内三层聚合口对接。FW主设备的设备内三层聚合口编号应与备设备的设备内三层聚合口编号保持一致。防火墙省略安全域和安全策略配置。 Border设备配置&#xff1a;采用M-LAG组…

嵌入式学习49-单片机2

指令周期 1M 机器周期 12M &#xff08;晶体震荡器产生&#xff09; 中断两种方式 …

创建型模式--1.单例模式【巴基速递】

1. 巴基的订单 在海贼世界中&#xff0c;巴基速递是巴基依靠手下强大的越狱犯兵力&#xff0c;组建的集团海贼派遣公司&#xff0c;它的主要业务是向世界有需要的地方输送雇佣兵&#xff08;其实是不干好事儿&#xff09;。 自从从特拉法尔加罗和路飞同盟击败了堂吉诃德家族 &…

怎么把学浪的视频保存到手机

越来越多的人在学浪app里面购买了课程并且想要下载下来&#xff0c;但是苦于没有方法或者工具&#xff0c;所以本文将教大家如何把学浪的视频保存到手机随时随地的观看&#xff0c;再也不用担心课程过期的问题。 本文将介绍工具来下载&#xff0c;因为下载方法太复杂&#xff…

Yolov5改进算法之添加Res2Net模块

目录 1. Res2Net介绍 1.1 Res2Net的背景和动机 1.2 Res2Net的基本概念 2. YOLOV5添加Res2Net模块 Res2Net&#xff08;Residual Resolution Network&#xff09;是一种用于图像处理和计算机视觉任务的深度卷积神经网络架构。它旨在解决传统的ResNet&#xff08;Residual Ne…

【JVM性能调优】- 阿里在线排除工具 - Arthas

阿里在线排除工具 - Arthas Arthas&#xff08;阿尔萨斯&#xff09;是阿里开源的一款Java在线诊断工具&#xff0c;官网原话&#xff1a;当你遇到以下类似问题而束手无策时&#xff0c;Arthas可以帮助你解决&#xff1a; 这个类从哪个 jar 包加载的&#xff1f;为什么会报各种…

千视携 NDI 6 轻量化媒体方案亮相北京CCBN展会

展会简介 第30届中国国际广播电视网络技术展览会&#xff08;CCBN&#xff09;将于4月24至26日在北京首钢会展中心举行。此次展会将汇集全球各大数字媒体、广播电视单位以及IT、通信技术厂商。展会重点关注数字化转型、智能媒体、融媒体等主题&#xff0c;并展示最新的5G、4K/8…

Day107:代码审计-PHP模型开发篇MVC层RCE执行文件对比法1day分析0day验证

目录 MVC 架构 CNVD-代码执行1day-lmxcms1.40版本 CNVD-命令执行1day-baijiacms4.1.4版本 知识点&#xff1a; 1、PHP审计-MVC开发-RCE&代码执行 2、PHP审计-MVC开发-RCE&命令执行 3、PHP审计-MVC开发-RCE&文件对比 MVC 架构 MVC流程&#xff1a; Controller截…

HCLR-Net: 混合对比学习正则化与局部随机扰动用于水下图像增强

论文地址&#xff1a;https://doi.org/10.1007/s11263-024-01987-y 源码&#xff1a;https://github.com/zhoujingchun03/HCLR-Net 摘要&#xff1a; 由于水下环境复杂多样&#xff0c;导致光吸收、散射和色彩失真等严重退化现象&#xff0c;因此水下图像增强是一项重大挑战…

Day108:代码审计-PHP模型开发篇MVC层动态调试未授权脆弱鉴权未引用错误逻辑

目录 案例1-Xhcms-动态调试-脆弱的鉴权逻辑 案例2-Cwcms-动态调试-未引用鉴权逻辑 案例3-Bosscms-动态调试-不严谨的鉴权逻辑 知识点&#xff1a; 1、PHP审计-动态调试-未授权安全 2、PHP审计-文件对比-未授权安全 3、PHP审计-未授权访问-三种形态 动态调试优点: 环境配置&…

Embedding:跨越离散与连续边界——离散数据的连续向量表示及其在深度学习与自然语言处理中的关键角色

Embedding嵌入技术是一种在深度学习、自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域广泛应用的技术&#xff0c;它主要用于将高维、复杂且离散的原始数据&#xff08;如文本中的词汇、图像中的像素等&#xff09;映射到一个低维、连续且稠密的向量空间中。这些低…

1111111111111111111111111

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

活动图高阶讲解-15

1 00:00:00,000 --> 00:00:07,200 目前来说&#xff0c;这个菱形到底是分还是合 2 00:00:07,200 --> 00:00:13,600 这个是靠入边出边的数量来判断的 3 00:00:13,600 --> 00:00:22,560 有的方法学&#xff0c;它可能会这样搞一些花样 4 00:00:22,560 --> 00:00:2…

Adobe InDesign 2024 v19.3 (macOS, Windows) - 版面设计和桌面出版软件

Adobe InDesign 2024 v19.3 (macOS, Windows) - 版面设计和桌面出版软件 Acrobat、After Effects、Animate、Audition、Bridge、Character Animator、Dimension、Dreamweaver、Illustrator、InCopy、InDesign、Lightroom Classic、Media Encoder、Photoshop、Premiere Pro、Ad…

室友打团太吵?一条命令让它卡死

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;更多干货&#xff0c;请关注专栏《网络安全自学教程》 SYN Flood 1、hping3实现SYN Flood1.1、主机探测1.2、扫描端…

鸿蒙(HarmonyOS)APP开发实战课程(入门到精通)

2024培训课程 2024技术交流群 CSDN在线课程地址: https://edu.csdn.net/course/detail/39448 推荐阅读 鸿蒙Harmony OS核心架构 鸿蒙内核源码分析(系统调用篇) 鸿蒙(HarmonyOS)APP开发培训课程 鸿蒙(HarmonyOS)APP开发实战课程 鸿蒙系统&#xff08;HarmonyOS&#xff0…

KNN课堂(分类课堂(可用kd树/特征归一化提高精度)))

实验代码&#xff1a; # 导入所需要的库 import numpy as np import pandas as pd from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 导入数据集 df pd.…

【Java集合进阶】LinkedList和迭代器的源码分析泛型类、泛型方法、泛型接口

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

ElasticSearch索引库操作

文章目录 1、简介2、mapping映射属性3、索引库的CRUD3.1、创建索引库和映射3.2、查询索引库3.3、修改索引库3.4、删除索引库3.5、总结 ​&#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;…