首页 > 编程语言 >JavaScript 基础

JavaScript 基础

时间:2022-10-06 14:44:12浏览次数:91  
标签:... name 对象 JavaScript 基础 let user 属性

1. 对象

对象创建

创建对象的两种方法:

  • 构造函数:let user = new Object();
  • 字面量:let user = {};

对象是属性可以随意添加:

  • 点号:user.name="Mason"
  • 方括号:user["age"]=26

对象字面量中可以用 [变量] 来表示属性名,叫做 计算属性

let fruit = prompt("which fruit? ", "apple");
let bag = {
    [fruit]: 5, // 属性名从 fruit 变量中动态得到
}
alert(bag.apple);

属性简写:

function makeUser(name, age) {
    return {
        name,
        age,
    }
}
// 相当于
function makeUser(name, age) {
    return {
        name: name,
        age: age,
    }
}

属性存在性测试:in

尝试访问 JavaScript 对象的不存在的属性时,不会报错,只是得到一个 undefined 值。使用 in 操作符可以检查对象中是否存在指定属性:"name" in user

对象引用与复制

引用复制:对象名被赋值给另一个变量时,复制的只是 对象的地址

浅拷贝:Object.assign(dest, src1, src2),该方法将若干个源对象中的每一个属性复制到目标对象中,但如果某个属性的值是一个嵌套对象,那么只会复制这个对象的引用。

深拷贝:使用 for attr in obj 循环,遍历每一个属性。

对象方法

可以给对象绑定一个函数作为属性:

let user = { name: "Rachael" }
user.sayHi = function() {
    console.log("Hi Monica.");
}

还可以在声明对象的时候绑定方法,这时可以用简写形式:

let user = {
    sayHi() { console.log("hello"); }
}

对象方法中的 this 指向该方法所在对象。

可选链 ?.

如果访问一个对象不存在的属性,会返回 undefined,但是如果访问这个不存在属性的属性,那就回出现错误,因为不能试图从 undefined 类型上获取属性。这种情况下,如果属性链又比较长的话,如果 对一个个属性手动检查是否存在 就太麻烦了,所以可选链 ?. 被引入了。

如果可选链前面的部分是 undefinednull,就会停止后面的运算并返回前面这部分的值。

例如 value?.prop

  • 如果 value 存在(不为 null 且不为 undefined),则尝试正常访问其 prop 属性;
  • 否则,返回 undefined,而不是出现错误。

所以下面就是一种使用可选链安全访问 user.address.street 的方式:

console.log( user?.address?.street );

除了用于安全访问对象属性,可选链还可以用来 安全地调用函数?.()

user.sayHi?.();

另外如果想要用方括号语法 访问属性,还可以用 ?.[]

console.log(user1?.["firstName"]);

Symbol

对象的属性只能是字符串类型或者 Symbol 类型。

Symbol 值表示唯一的标识符,使用 Symbol() 函数来创建,可以在创建时给函数传入一个字符串作为该 Symbol 值的描述(名字),名字不影响 Symbol 的唯一性。

用途之一——给对象添加隐藏属性:

Symbol 作为对象的属性名时,只能在当前文件访问到这个属性,在外部访问不到这个 Symbol:

let user = { name: 'Mason' }; // 外部对象
let id = Symbol("id");
user[id] = 1; // 只能用方括号语法来定义这个属性,因为属性名引用的是一个变量
console.log(user[id]);

Symbol 类型的值作为对象的属性名时,会被属性的 for...in... 循环忽略,但是在使用 Object.assign() 拷贝对象属性时,会被访问到。

全局 Symbol

常规情况下,即使多个 Symbol 有相同的名字,它们也是不同的值,但是如果希望维护一个全局的 Symbol,在不同地方都可以 通过同样的名字访问,且确保访问到的是同一个 Symbol,就可以使用 全局 Symbol 注册表

// 从全局注册表中读取,不存在会新建
let id = Symbol.for("id");
let idAgain = Symbol.for("id");
console.log(id === idAgain); // true

2. 数据类型

数字

进制转换nums.toString(base) 返回给定进制下 num 的字符串表示形式。

舍入Math.floorMath.ceilMath.round(四舍五入)。

保留指定位数小数num.toFixed(2)num 保留 2 位小数后以字符串形式返回,然后将字符串转为数字即可。

字符串转为数字

  • Number(str)
  • +str(一元加号)
  • parseInt(),parseFloat():一元加号 +Number() 函数需要被转换的字符串除了开头结尾空格之外,所有字符都是数字。而 parseInt()parseFloat() 可以删除开头空格之后从头开始解析,解析出开头连续的数字,遇到第一个非数字字符后返回解析结果。如果是 a12 这种以非数字开头的,会返回 NaN

isNaN()

它会首先尝试将参数转换为数字,然后检查转换结果是否为数字:

isNaN("a12"); // true
isNaN("12"); // false

之所以有这个函数,是因为 NaN 这个值跟任何值都不相等,包括自身

Math 对象

  • Math.random() 返回一个 [0,1) 的随机数;
  • Math.max(a,b,c,...), Math.min(a,b,c,...) 最值
  • Math.pow(n, power)

字符串

三种引号:支持单引号、双引号、反引号,反引号允许通过 ${expression} 嵌入表达式,且允许多行字符串。

访问字符

  • 使用下标:str[pos](现代)
  • 使用方法:str.charAt(pos)(以前)

如果没有找到字符,下标会返回 undefined,方法会返回空串。

遍历字符串for (left c of str)

字符串长度length 属性。

字符串不可变:不能通过下标的方式修改字符串中某个位置的字符。

子串相关方法

  • 查找子串:str.indexOf(substr),找不到会返回 -1includes(sub)startsWith(sub)/endsWith(sub)
  • 获取子串:slice(start, end),获取 [start, end) 区间的子串。substring(s,e)/substr(s,e) 作用和 slice(s,e) 相同,但主要使用 slice() 方法。

比较字符串

  • str.codePointAt(pos):返回指定位置字符的 ASCII 码
  • String.fromCodePoint(code):返回指定 ASCII 码对应的字符
  • str1.localeCompare(str2):表示两字符的字典序关系,如果 str1str2 之前,则返回负数。

数组

数组长度length 属性,可以手动修改这个属性,如果减少会导致数组被截断,所以 清空数组 的一个方法就是将 length 属性设为 0

元素类型:一个数组中的元素可以是各种类型的。

遍历

  1. 常规 for i 循环
  2. for...of... 循环:for (let name of names)
  3. forEach 循环:arr.forEach(function(item, index, array)) { ... }

常用 API:

  • 删除/插入元素splice(start, [deleteCount, newElem1, newElem2, ...]):删除从 start 位置开始的 deleteCount 个元素,并在删除位置插入新元素。将 deleteCount 设置为 0,就可以不删除只插入。

  • slice(start, end)获取一个切片,左闭右开,索引支持负数。如果不指定 start,会从第一个元素开始切分;如果不指定 end,会切分到最后一个元素。

  • concat(arg1, arg2, ...):参数可以是单个的值,也可以是一个数组,将所有参数 拼接到原数组 之后返回。

  • 查找元素indexOf(item, [start]):找不到则返回 -1includes(item, [start]):判断 item 是否存在。inlcudes() 可以正确处理 NaN,而 indexOf() 不能。

  • 搜索满足指定条件的元素

    • find(item => item.name == "Rachael")findIndex(item => item.name == "Rachael") —— 返回满足条件的 第一个 元素、元素的索引。找不到则返回 undefined/-1
    • filter(user => user.age > 18) —— 返回满足条件的 所有 元素,返回一个数组。
  • 排序

    • sort() 原地排序,可以传入一个函数表示排序依据:sort((a,b) => a-b ) —— 表示从小到大排序。
    • reverse() 原地逆序
  • 分割str.split(sep) 将一个字符串根据指定分隔符(默认为空字符)分割为 字符数组arr.join(sep) 刚好相反,将一个数组中的各个元素根据指定分隔符连成字符串。

  • 元素映射arr.map(function(item, index, array) { ... }):在每个元素上调用一遍函数。

  • 迭代reduce/reduceRight

    let value = arr.reduce(function(accumulator, item, index, array) {
        //...
    }, [initial]); // initial 是迭代结果的初值
    

    例如:

    let arr = [1,2,3,4];
    let sum = arr.reduce((sum, item) => sum + item, 0);
    
  • Array.from() 将一个 array-like 对象转换为数组。所谓 array-like 对象,就是有索引和 length 属性的对象。

Map

Map 和 JavaScript 对象在形式上很像,但是 Map 允许任何类型的键,还提供了一系列方法。

let map = new Map();
map.set('1', 'str1');
map.set(1, 'num1');
map.size // 2
map.has(1) // true
map.delete(1)

甚至也可以将 JavaScript 对象作为 Map 的键。

set() 方法返回当前对象,所以可以链式调用。

遍历

三个方法:keys(), values(), entries()

for (let k of map.keys())
    console.log(map.get(k));

也可以用 forEach()

map.forEach((value, key, map) => {
    // ... 注意第一个参数是 value,第二个才是 key
})

对象和 Map 的转化

  • JavaScript 对象 → Map:Object.entries(obj) 方法可以将 JavaScript 对象转换为 二维的键值对数组[[key1, value1], [key2, value2], ...],将这样的数组传入 Map() 构造函数就可以构造出一个 Map。
  • Map → JavaScript 对象:Object.fromEntries() 方法相反,负责根据给定的二维键值对数组创建 JavaScript 对象:Object.fromEntries(map.entries())

Set

let set = new Set();
let rachael = { name: "Rachael" }
let monica = { name: "Monica" }
set.add(rachael)
set.add(monica)
set.size // 2
// for of 循环
for (let friend of set) console.log(friend.name)
// forEach 循环
set.forEach((value) => console.log(value))

解构赋值

数组解构

let arr = ["Chandler", "Bing"]
let [first, last] = arr

或者:

let [first, last] = "Mason Li".split(" ")

可以 使用逗号忽略一个位置的值:

let [name, , age] = ["Chandler", "Bing", 27]

等号右侧可以是任何 可迭代对象

用途 1:通过解构 遍历对象的键值对

for (let [key, value] of Object.entries(user)) { ... }

用途 2:交换多个变量的值

[val1, val2] = [val2, val1]

用途 3:使用 rest 参数...arg)可以接收剩余的所有参数:

// rest 会成为一个数组
let [name1, name2, ...rest] = ["Rachael", "Chandler", "Monica", "Febbe"]

对象解构

根据 属性名 可以从对象中解构出对应属性:

  • 属性名的顺序不重要
  • 可以给变量设置 默认值
let options = {
    title: "Menu",
    width: 100,
    height: 200
}
let {width=150, height=250, title} = options;

还可以把一个属性赋值给另一个名字的变量:

let {width: w = 150, height: h = 250} = options

rest 参数:

let {title, ...rest} = options

不使用 let 而直接用花括号进行解构时,会出错:

let title, width, height;
{title, width, height} = options // 出错

这是因为 JavaScript 会把花括号中的内容当做一个代码块。

为了告诉 JavaScript 这不是一个代码块,可以把整个赋值表达式用圆括号包裹起来:

({title, width} = options)

嵌套解构

嵌套解构会 解构到最内层外层的变量不会被赋值

let options = {
    item: ["Cake", "Donut"],
    size: {
        width: 200,
        height: 100
    }
};
let {
    size: {
        width,
        height
    },
    item: [item1, item2]
} = options;

item // Error
size // Error
item1 // "Cake"
width 200

用对象作为函数参数

function showMenu({title = "untitled", width = 200, height = 100}) {
    // ...
}
let options = {
    title: "My Menu",
    items: ["item1", "item2"]
};
showMenu(options);

JSON

将 JavaScript 对象转换为 JSON 字符串 —— JSON.stringify()

JSON 对象与 JavaScript 对象有两个区别:

  • JSON 对象没有单引号或反引号,只用双引号
  • JSON 对象的 属性名也要用双引号

转换时会跳过一些特定于 JavaScript 对象的属性:

  • 方法
  • Symbol 类型属性
  • 值为 undefined 的属性

将 JSON 字符串转换为 JavaScript 对象 —— JSON.parse()

3. 函数

函数没有返回值时,默认返回 undefined

Rest 参数与 Spread 语法

Rest 参数

调用函数时传入参数多于函数定义时参数个数也不会出错,但是多余的参数会被忽略。使用 Rest 参数可以 将剩余参数收集到一个数组中。

function getGrade(name, ...grades) {
    console.log(name)
    for (let grade of grades)
        console.log(grade)
}

Rest 参数必须放到参数列表末尾。

Spread 语法

Spread 语法形式上和 rest 参数很像,也是使用三个点 ...,但是作用刚好相反,它是 将一个可迭代对象中的所有元素展开成参数列表。

let arr = [1,3,5];
let max = Math.max(...arr); // 展开式语法

还可以同时 传递多个可迭代对象,并能同时与常规参数结合使用:

let max = Math.max(0, ...arr1, ...arr2, 7);

除了函数调用,Spread 语法的其他用法:

  • 合并数组:

    let merge = [...arr1, 10, ...arr2, 20];
    
  • 复制数组:

    let arrCopy = [...arr];
    
  • 复制对象:

    let objCopy = {...obj};
    

使用 Spread 语法复制数组或对象比 Object.assign() 方法简洁很多,所以这种方式更为常用。

装饰器模式

可以给函数传入一个函数作为参数。

例如有一个耗时操作 slow(),为了提高它的速度,可以将它的执行结果缓存下来,再次调用时,如果对应的缓存结果存在,就直接返回这个缓存。

function slow(x) { ... }
function cacheSlow(func) {
    let cache = new Map();
    return function(x) {
        if (cache.has(x)) return cache.get(x);
        let result = func(x); // 没有缓存再调用
        cache.set(x, result);
        return result;
    };
}

这里再函数内返回了一个函数,这种语法现象叫做 闭包,所谓闭包,就是 携带状态的函数,或者说,闭包是 一个函数及其绑定的周边环境的组合。在执行完 cacheSlow() 函数之后,它内部的局部变量 cache 不会被回收,因为它还被内部的函数引用。(所以这个变量被分配到堆区)

call/apply

call()/apply() 这两个高阶函数可以 给其他函数绑定 this

func.call(context, arg1, arg1)
function sayHi() { console.log("Hi " + this.name); }
let friend = { name: "Rachael" };
sayHi.call(friend); // "Hi Rachael"

apply()call() 唯一的不同在于调用方式,call 接收一个参数列表,而 apply 接收一个包含这些参数的 类数组对象

func.call(context, ...args) // args 是一个类数组对象,将其展开为参数列表
func.apply(context, args) // 直接传入对象

绑定 this

一旦方法被传递到 与对象分开 的某个地方,this 就会丢失。

let user = {
    name: "Mason",
    sayHi() { console.log(`Hello, ${this.name}`); }
};
setTimeout(user.sayHi, 1000); // sayHi 方法与 user 对象分开了,this 变成了全局对象

使用 bind() 方法可以给一个函数绑定任意 this

let friend = { name: "Rachael" };
function getName() { console.log(this.name); }
let getNameBinded = getName.bind(friend);
getNameBinded(); // "Rachael"

箭头函数

箭头函数没有 this,如果访问 this,它会从外部获取。

let group = {
    groupId: 1,
    names: ["Mason", "John", "Mike"],
    showList() {
        this.names.forEach(
        	name => console.log(this.groupId + name)
        ); // 能够正确获取 this.groupId
    }
};
group.showList(); // 正确运行

因为没有自己的 this,所以上面的箭头函数会到外部(即 group 对象)获取 this。而普通函数是有 this 的,默认为 undefined

因为不具有 this,所以也就不能将箭头函数用作构造器,不能用 new 调用它。

4. 原型和继承

__proto__ 属性

对象有一个隐藏属性 [[Prototype]],指向其原型(父类型),如果没有原型则为 null

从对象中读取一个不存在的属性时,会自动往原型中查找这个属性,这就是“原型继承”行为。

访问/修改 [[Prototype]] 属性的方式为

  • __proto__ 属性。__proto__ 属性是 [[Prototype]] 属性的 getter/setter,这是历史遗留问题,已经不推荐使用。
  • 推荐使用 Object.getPrototypeOf()Object.setPrototypeOf() 方法。

属性的迭代

使用 for in 循环迭代对象属性时会包含继承自原型的属性,如果不想考虑这些属性,可以通过 obj.hasOwnProperty(prop) 判断条件来过滤,如果 prop 是从原型继承来的,会返回 false

prototype 属性

JavaScript 的所有 函数 都有 prototype 属性。

JavaScript 对象分为 函数对象普通对象,每个对象都有 __ptoto__ 属性,但只有函数对象才有 prototype 属性。

构造函数、实例、原型三者的关系

(构造)函数prototype 属性指向了一个对象,这个对象就是那些被该函数构造出来的所有 实例对象原型(或者说父对象,__proto__ 所指对象),每个对象都能从原型对象继承属性。

实例的 __proto__ 指向构造函数的 ptototype 对象。

每个原型都有一个 constructor 属性,指向关联的 构造函数

function Person() {} // 构造函数
let person = new Person(); // 实例对象
person.__proto__ === Person.prototype // true
Person.prototype.constructor === Person // true

原型链

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

那么,原型的原型又是什么呢?

原型也是一个 对象,是通过 Object() 构造函数 生成的,那么原型就是这个构造函数的实例,那么它的原型就指向 Object.prototype 对象。

Object.prototype 对象是顶层对象,它的原型被设计为 null

参考:https://github.com/mqyqingfeng/blog/issues/2

5. Class

语法

class User {
    // 构造函数:在这里定义类的数据域
    constructor(name) { this.name = name; }
    // 方法
    sayHi() { console.log("Hi " + this.name); }
}
let user = new User("Rachael");
user.sayHi(); // "Hi Rachael"

类属于函数

typeof User // function

声明类 class User { ... } 的时候,实际上做了下面两件事:

  1. 创建名为 User 的函数,函数体来自 constructor 方法。
  2. User 原型中存储类中声明的方法:User.prototype.sayHi 等。

但类不仅仅是语法糖

类和函数存在很大差异:

  1. 在类中创建的函数具有属性 [[IsClassConstructor]]:true
  2. 类方法不可枚举,所有方法的 enumerable 属性都为 false
  3. 类的其他功能。

getter/setter

class User {
    constructor(name) {
        this.name = name; // 调用 setter
    }
    get name() { // 用 get 关键字指明该方法为 getter
        return this._name;
    }
    set name(value) { // 用 set 关键之指明该方法为 setter
        this._name = value;
    }
}
let user = new User("Mary");
user.name // Mary
user.name = "Jenifer";
user.name // Jenifer

定义 getter/setter 之后,还是直接用属性名访问属性user.name),只是在 getter/setter 内部可以定义一些附加的逻辑。

继承

通过 extends 关键字建立原型链:

class Dog extends Animal { ... }

extendsDog.prototype.__proto__ 设置为了 Animal.prototype 对象,还将 Dog.__proto__ 设置为了 Animal

重写父类(原型)中的方法

super 关键字用来引用父类:

  • super.method() 调用父类的方法;
  • super(...) 调用父类构造函数。

箭头函数不能使用 super

子类的构造函数必须调用 super(),且必须在使用 this 之前就调用

静态成员

可以把一个方法赋值给类本身,而不是它的 prototype 对象,这样的方法是 static 方法。同样地,可以设置静态属性。

class User {
    static staticMethod() { ... }
    static staticField = "Hello";
}
User.staticMethod(); // 通过类直接调用

私有属性

受保护属性

受保护属性通常以下划线作为前缀,提醒开发者,这个属性不要从外部访问。但这只是一种约定,变量名加不加下划线实际上没有区别。

只读

要让某个属性只读,可以只给它设置 getter,而不设置 setter。这样从外部修改这个属性时就会报错。

私有属性

上面的受保护属性毕竟不受语言支持,所以最新的提案为私有属性和方法提供了语言级的支持:私有属性和方法以 # 符号开头,只能在类的内部被访问。这个提案即将/已经加入到最新的规范。

6. 异步

Promise

执行任务,返回 Promise 对象

let promise = new Promise(function(resolve, reject) {
    // ... 执行任务
})

在任务执行完毕时,可以调用 resolve(value)reject(error) 这两个函数之一,这是两个 JavaScript 提供的函数。

  • 如果正确完成了任务,就调用 resolve(value),这会将构造出的 Promise 对象的 state 属性变成 fulfilled,将 result 属性变成 value
  • 如果出现了错误,就调用 reject(error),这会将构造出的 Promise 对象的 state 属性变成 rejected,将 result 属性变成 error

Promise 对象的 stateresult 属性可以在后续的 .then() 方法中引用,来异步处理执行结果。

then、catch、finally 处理执行结果

.then() 可以接收两个回调函数作为参数,分别处理 resulterror。一条最佳实践是,.then() 中只处理 resulterror 放到 .catch() 中来处理。

.then() 中返回的值可以传入下一个 .then(),所以 .then() 可以链式调用。

Promise API

1️⃣ Promise.all([promise1, ...])

这个方法用得最多,接收 Promise 对象数组 作为参数,等 所有 Promise 对象都成功执行 后才返回一个结果,这个结果也是一个 Promise 对象,其 value 属性为各个 Promise 结果组成的数组。

一旦有一个 Promise reject 了,Promise.all 就会立即 reject,并将这个错误返回。

例子:

let names = ["Rachael", "Monica"]
let url = "https://friends.com/friend/"
let requests = names.map(name => fetch(`${url}${name}`))
Promise.all(request).then(...)

2️⃣ Promise.allSettled

Promise.all 类似,但它会等所有 Promise 对象都变成 settled 状态时才返回各个 Promise 的结果。(resolve 或者 reject 之后都会变成 settled 状态)

3️⃣ Promise.race

等任何一个 Promise 对象变成 settled 状态时就结束。

async/await

这两个关键字是 Promise 的语法糖。

async 函数

async 放在函数前面,确保函数的返回值是一个 Promise 对象,如果返回普通值,会被包装成一个 Promise 对象。

async function f() { return 1; }
f().then(console.log); // 1

await 关键字

await 关键字只能用在 async 函数中,它让 JavaScript 执行引擎等待,直到 Promise 执行完成。

async function f() {
    let promise = new Promise(
    	resolve => setTimeout(() => resolve("done"), 1000)
    );
    let result = await promise; // 主线程暂停执行,直到 promise 返回
    console.log(result); // 此时 result 已经有了期望的值
}

await 是用来代替 then 的,它以同步的方式书写异步代码

捕获错误

then 搭配使用的是 catch,而在 async/await 中,通常直接使用 try...catch

async function f() {
    try {
        let response = await fetch(url);
    } catch(err) {
        console.log(err);
    }
}

7. 模块

导出的语法:

1️⃣ 在声明前导出

可以在声明之前放置 export 来标记任意声明为导出:

export let names = ["Rachael", "Monica"];
export function f() { ... }

2️⃣ 导出与声明分开

先声明变量、函数等,然后在最后导出:

function foo() { ... }
function bar() { ... }
export {foo, bar}; // 导出变量列表

3️⃣ 默认导出

实际开发中主要有两种模块:

  • 包含 函数包 的模块
  • 声明 单个实体 的模块

大部分情况下,第二种方式更为推荐,这样可以让模块的组织更加规范。为此模块提供了一个特殊的 默认导出 语法,以便支持 一个模块只做一件事 这个原则。

export default class User {
    ...
}

一个文件 只能有一个默认导出,导入这种被默认导出的内容时,不需要写花括号:

import User from './user.js';

还有几点需要注意:

  • 一个文件可以同时存在默认导出和命名导出,但最好不要混合使用。但如果真的混合使用了,在导入的时候,需要使用 default 作为默认导出的名字。

  • 默认导出可以不指定名称(变量名、函数名等),这样的匿名默认导出在导入时可以随意指定名字,但指定的名字最好与模块名相同。

    // 

    标签:...,name,对象,JavaScript,基础,let,user,属性
    From: https://www.cnblogs.com/lzh1995/p/16757586.html

相关文章

  • Java程序员必备基础:JDK 5-15都有哪些经典新特性
    前言JDK15发布啦~我们一起回顾JDK5-15的新特性吧,大家一起学习哈~本文已经收录到github❝​​https://github.com/whx123/JavaHome​​❞「公众号:捡田螺的小男孩」Java5......
  • 如何将一个 JavaScript 数组打乱顺序
    当我们想将现有的数组打乱顺序,有两个方法:1.Array.prototype.sort()数组的sort()方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串......
  • 软件技术基础自我介绍与未来展望
    软件技术基础https://edu.cnblogs.com/campus/zjlg/22rjjc这个作业的目标<发表一篇关于自我介绍与课程展望的博客;熟悉一下markdown编辑器使用;姓名-学号<郑雷......
  • python基础--基本概念
    1.脚本的文件格式  脚本名.py  eg:hello.py2.脚本结构  大概三部分,脚本头+导入部分+业务模块  每一块都是非必须的,按需填写即可;    为了书写规范,一般......
  • Android 滑动效果基础篇(三)—— Gallery仿图像集浏览
    Android系统自带一个Gallery浏览图片的应用,通过手指拖动时能够非常流畅的显示图片,用户交互和体验都很好。本示例就是通过Gallery和自定义的View,模仿实现一个仿Gallery图......
  • Metasploit训练基础-嗅探网络
    嗅探网络usesniffer查看嗅探文档help查看网卡信息sniffer_interfaces选择网卡sniffer_start1查看抓包状态snifferstats1转存抓包文件sniffer_dump1hacked.pcap抓包脚......
  • 进程通信基础
    进程同步与进程通信很容易混淆,它们的区别在于:进程同步:控制多个进程按一定顺序执行;进程通信:进程间传输信息。进程通信是一种手段,而进程同步是一种目的。也可以说,为了能......
  • JavaScript回调函数
    在百度百科中,回调函数的定义就是一个被作为参数传递的函数。通俗地理解:我现在写一个函数,里面定义了函数A,那么函数A就是回调函数。以前我认为JavaScript不过是......
  • 今天重新学习java基础的时候遇到了一个好玩的问题。换了环境变量jdk还是显示原来版本
    今天学习ES,需要用到更高版本的jdk(我以前用的是1.8),所以要更改以前的jdk设置,总体步骤如下:1.下载jdk-11,解压2.打开环境变量配置,把以前配置的JAVA_HOME的改为新jdk-11的路径......