js 基础 - 个人杂记 - 简解

306 阅读9分钟

Truthy 与 Falsy

falsy 值 (虚值) 是在 Boolean上下文中认定为 false 的值。

JavaScript在需要用到布尔类型值的上下文中使用强制类型转换(Type Conversion)将值转换为布尔值,例如条件语句和循环语句。

js只有8个Falsy值(false,0,-0,0n(当BigInt作为布尔值使用时, 遵从其作为数值的规则. 0n 是 falsy值.),空字符串("", '', ``),null,undefined,NaN),其它均为Truthy值。

数组常用方法

1.push(末尾添加一个或多个元素(,隔开),返回新长度) / pop(删除并返回最后一个元素)
2.unshift(开头添加一个或多个元素(,隔开),返回新长度) / shift(删除并返回第一个元素)
3.every(所有元素符合条件才返回true) / some(一个元素符合条件就返回true)

let ages = [32, 33, 16, 40];
function checkAdult(age) {
  return age >= 18;
}
console.log(ages.every(checkAdult)); //false 并非所有age都大于等于18

4.indexOf(正序搜索元素并返回第一个匹配位置) / lastIndexOf(倒序搜索元素并返回倒序的第一个匹配位置) / includes(检查数组是否包含指定的元素返回boolean)
5.reduce(将数组的值处理为单个值(从左到右),不改变原始数组) / forEach(为每个数组元素调用函数) / map(为每个数组元素调用函数的结果创建新数组,不改变原始数组) / filter(数组中通过测试的每个元素创建新数组,不改变原始数组)

// 4个例子各种单独运行
// reduce
let numbers = [175, 50, 25];
function myFunc(total, num) {
    return total - num;
}
console.log(numbers.reduce(myFunc)); //100

// forEach
let text = "";
const fruits = ["apple", "orange", "cherry"];
function myFunction(item, index) {
    text += index + ": " + item + "<br>";
}
fruits.forEach(myFunction);
console.log(text);// 0: apple<br>1: orange<br>2: cherry<br>

// map
const numbers = [4, 9, 16, 25];
console.log(numbers.map(Math.sqrt)); //[ 2, 3, 4, 5 ]

// filter
let ages = [32, 33, 16, 40];
function checkAdult(age) {
  return age >= 18;
}
console.log(ages.filter(checkAdult)); //[ 32, 33, 40 ]

6.slice(选择数组的一部分(从给定的start参数(包括,可选,没有则起复制作用)开始的元素,并在给定的end参数(不包括,可选,没有则起复制到尾)处结束),不改变原始数组返回新数组) / splice(从数组中添加/删除元素(参数:index-必需,指定在什么位置添加/删除项目,howmany-可选,要删除的项目数,item1, ..., itemX -可选,要添加到数组中的新元素),改变原始数组返回删除项目)

// slice
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
console.log(fruits.slice(1, 3)); //[ 'Orange', 'Lemon' ]

// splice
let fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 1, "Lemon", "Kiwi");
console.log(fruits); //[ 'Banana', 'Orange', 'Lemon', 'Kiwi', 'Mango' ]

7.entries(返回键/值对数组迭代(Array Iterator)对象,不改原始数组) / keys(返回 Array Iteration 对象,包含原始数组的键)

// entries
const fruits = ["Banana", "Orange", "Apple", "Mango"];
const f = fruits.entries();
console.log(f); //Object [Array Iterator] {}
for (let x of f) {
  console.log(x); //[ 0, 'Banana' ],[ 1, 'Orange' ],[ 2, 'Apple' ],[ 3, 'Mango' ]
}

// keys
let fruits = ["Banana", "Orange", "Apple", "Mango"];
let fk = fruits.keys();
console.log(fk) // Object [Array Iterator] {}
for (let x of fk) {
  console.log(x); // 0,1,2,3
}

8.join(将数组的所有元素连接成一个字符串,不改变原始数组)
9.sort(对数组的元素进行排序,改变原始数组) / reverse(反转数组中元素的顺序,改变原始数组)

// sort
const points = [40, 100, 1, 5, 25, 10];
points.sort(function(a, b){return b-a});
console.log(points); //[ 100, 40, 25, 10, 5, 1 ]

对象常用方法

1.创建对象与修改原型链:

  • Object.create(proto,[propertiesObject])(创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。proto-新创建对象的原型对象。propertiesObject-可选。需要传入一个对象,该对象的属性类型参照[Object.defineProperties()方法]的第二个参数。)
  • Object.assign(target, ...sources)(target-目标对象。sources-源对象。目标对象与源对象具有相同的键时,目标对象属性将被源对象的属性覆盖。)
  • Object.setPrototypeOf(obj, prototype)(obj-要设置其原型的对象。prototype-该对象的新原型(一个对象或null)设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或null。)
// Object.create
const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};
const me = Object.create(person);
const she = Object.create({}, { p: { value: 42 } })

me.name = 'Matthew';
me.isHuman = true;

me.printIntroduction();// expected output: "My name is Matthew. Am I human? true"

console.log('she',she) //she {p: 42}
console.log(me) //{name: 'Matthew', isHuman: true}
console.log(me.__proto__) //{isHuman: false, printIntroduction: ƒ}

// Object.assign
const obj = {
  a: 1
};
const copy = Object.assign({
  a: 2,
  b: 2
}, obj);
console.log(copy); // {a: 1, b: 2} 

// Object.setPrototypeOf
var dict = Object.setPrototypeOf({}, null);

2.获取对象属性

  • Object.keys(obj)(obj-遍历对象,返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致。)
  • Object.values(obj)(obj-遍历对象,返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。)
  • Object.entries(obj)(返回一个给定对象自身可枚举属性的键值对数组,其排列与使用for...in循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。)
  • Object.getOwnPropertyNames(obj)(返回一个数组,该数组对元素是 obj自身拥有的枚举或不可枚举属性名称字符串。数组中枚举属性的顺序与通过for...in循环(或Object.keys)迭代该对象属性时一致。数组中不可枚举属性的顺序未定义。与Object.keys区别是会加带出不可枚举属性名称字符串)
  • Object.getOwnPropertySymbols(obj)(返回一个给定对象自身的所有 Symbol 属性的数组。)
var obj = { 0: 'a', 'kk': 'kk', 2: 'c'};
Object.defineProperty(obj,'jj',{
	value: 'jj',
	enumerable: false,
})
obj[Symbol("oo")] = "Symboloo";

console.log(Object.keys(obj)); // ['0', '2', 'kk']
console.log(Object.values(obj)); // ['a', 'c', 'kk']
console.log(Object.entries(obj)); // [['0', 'a'],['2', 'c'],['kk', 'kk']]
for (const [key, value] of Object.entries(obj)) {
  console.log(`${key}: ${value}`); // 0: a // 2: c // kk: kk
}

console.log(Object.getOwnPropertyNames(obj)); // ['0', '2', 'kk', 'jj']
console.log(Object.getOwnPropertySymbols(obj)); //[Symbol(oo)]

3.修改对象属性

  • Object.defineProperty(obj, prop, descriptor)(直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。查看之前详细记录(juejin.cn/post/705411…
  • Object.defineProperties(obj, props)(obj-在其上定义或修改属性的对象。props-要定义其可枚举属性或修改的属性描述符的对象。)
// Object.defineProperty
const object1 = {};
Object.defineProperty(object1, 'property1', {
  value: 42,
  writable: false
});
object1.property1 = 77; // 修改不了
console.log(object1.property1); //42

// Object.defineProperties
var obj = {};
Object.defineProperties(obj, {
  'property1': {
    value: true,
    writable: true
  },
  'property2': {
    value: 'Hello',
    writable: false
  }
  // etc. etc.
});
console.log(obj) //{property1: true, property2: 'Hello'}

4.获取对象的属性描述符

  • Object.getOwnPropertyDescriptors(obj)(获取一个对象的所有自身属性的描述符。)
  • Object.getOwnPropertyDescriptor(obj, prop)(obj-需要查找的目标对象,prop-目标对象内属性名称,返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性))
const object1 = {
  property1: 42,
  property2: 43,
};
console.log(Object.getOwnPropertyDescriptors(object1))
//{property1:{configurable: true,enumerable: true,value: 42,writable: true},property2:{configurable: true,enumerable: true,value: 43,writable: true}}
console.log(Object.getOwnPropertyDescriptor(object1, 'property1')) //{value: 42, writable: true, enumerable: true, configurable: true}

5.冻结,密封,不可拓展对象

  • Object.freeze(obj)(obj-要被冻结的对象。被冻结对象自身的所有属性都不可能以任何方式被修改。)
  • Object.isFrozen(obj)(obj-检测对象,返回BOOLEAN。一个对象是冻结的是指它不可扩展,所有属性都是不可配置的,且所有数据属性(即没有getter或setter组件的访问器的属性)都是不可写的。)
  • Object.seal(obj)(obj-要被密封的对象。通常,一个对象是可扩展的(可以添加新的属性)。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。)
  • Object.isSealed(obj)(如果这个对象是密封的,则返回 true,否则返回 false。密封对象是指那些不可扩展的,且所有自身属性都不可配置且因此不可删除(但不一定是不可写)的对象。)
  • Object.preventExtensions(obj)(让一个对象变的不可扩展,也就是永远不能再添加新的属性。)
  • Object.isExtensible(obj)(判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。)
// Object.freeze / Object.isFrozen
const obj = {
  prop: 42
};
Object.freeze(obj);
obj.prop = 33; // 修改不了
console.log(obj.prop); // 42
console.log(Object.isFrozen(obj)) //true

// Object.preventExtensions / Object.isExtensible
const object1 = {};
Object.preventExtensions(object1);
try {
  	Object.defineProperty(object1, 'property1', {
    	value: 42
  	});
} catch (e) {
	console.log(Object.isExtensible(object1)); //false
  	console.log(e);// TypeError: Cannot define property property1, object is not extensible
}

6.其它

  • Object.is(value1,value2)(判断两个值是否为同一个值。)
//Object.is
let value1 = {a:1}
let value2 = {a:1}
let value3 = value1;
console.log(Object.is(value1, value2)); //false
console.log(Object.is(value1, value3)); //true

var, let 和 const 区别

var: var用于创建一个可变变量,存在变量声明提升。

const: 它用于创建一个不可变变量,不可变变量是指其值在程序的整个生命周期中永不改变的变量。

let: let用于创建一个可变变量,可变变量是像var这样的普通变量,可以任意次数地更改。

注意点:如用const声明person对象,给age重新赋值是没问题的
但是重新给person赋值是不可以的

  1. const声明的是常量,必须赋值
    1)一旦声明必须赋值,不能使用null占位。
    2)声明后不能再修改
    3)如果声明的是复合类型数据,可以修改其属性
  2. let和var声明的是变量,声明之后可以更改,声明时可以不赋值
  3. var允许重复声明变量,后一个变量会覆盖前一个变量。let和const在同一作用域不允许重复声明变量,会报错。
  4. var声明的变量存在变量提升(将变量提升到当前作用域的顶部)。即变量可以在声明之前调用,值为undefined。let和const不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报ReferenceError错。
  5. var不存在块级作用域。let和const存在块级作用域。ES5中作用域有:全局作用域、函数作用域。没有块作用域的概念。ES6(简称ES6)中新增了块级作用域。块作用域由 { } 包括,if语句和for语句里面的{ }也属于块作用域。

注意点:

for in 与for of区别

  • for of 循环用来获取一对键值对中的值,而 for...in 获取的是键名
  • 一个数据结构只要部署了 Symbol.iterator 属性, 就被视为具有 iterator接口, 就可以使用 for of循环。

原型和原型链:

blog.csdn.net/Yi_qian1000…

promise详解

blog.csdn.net/m0_73916603…

cookie session localStorage sessionStorage 区别

blog.csdn.net/m0_65084430…