Java Script相关知识点整理

本文详细介绍了JavaScript的数据类型,包括基本数据类型和引用数据类型,重点解析了它们的区别,如栈内存与堆内存的概念。此外,文章还涵盖了作用域、类型检测、字符串、数字、数组和对象等核心概念,以及函数、原型、正则表达式和DOM操作等。深入探讨了闭包、BOM与DOM交互,以及Promise和任务管理,为全面掌握JavaScript提供了基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据类型

基本数据类型:String, Boolean,Number,null,undefined 这5种之外的类型都称为Object
引用数据类型:Object, function, Array

区别:

  • 基本: 简单数据类型。变量保存在栈内存中, 比较两个基本数据类型的值本质是比较值
  • 引用: 对象数据类型。对象保存在堆内存中, 变量保存的是对象的内存地址.比较两个引用的本质是比较对象的内存地址

undefined:未赋值或未定义的变量值均为undefined
null:定义一个空对象
== 与 === 区别

1、对于 string、number 等基础类型,== 和 === 是有区别的
a)不同类型间比较,== 之比较 “转化成同一类型后的值” 看 “值” 是否相等,=== 如果类型不同,其结果就是不等。
b)同类型比较,直接进行 “值” 比较,两者结果一样。
2、对于 Array,Object 等高级类型,== 和 === 是没有区别的

null 与 undefined 区别

1)undefined:是所有没有赋值变量的默认值,自动赋值。
2)null:主动释放一个变量引用的对象,表示一个变量不再指向任何对象地址。
2、何时使用null
当使用完一个比较大的对象时,需要对其进行释放内存时,设置为 null。
3、null 与 undefined 的异同点
共同点:都是原始类型,保存在栈中变量本地。
不同点:
(1)undefined——表示变量声明过但并未赋过值。它是所有未赋值变量默认值,例如:var a; // a 自动被赋值为 undefined
(2)null——表示一个变量将来可能指向一个对象。一般用于主动释放指向对象的引用

作用域

  • let声明后的变量不允许在同一作用域中重新声明,不同作用域可以重新声明
  • 用var声明的是全局变量
  • 使用const声明的是常量,值无法改变

var关键字定义的变量可以先使用后声明。(变量提升)
let关键字定义的变量需要先声明再使用,全局声明的变量不存在于window对象中(与var不同)。
const关键字定义的常量,声明时必须进行初始化,且初始化后不可再修改。

类型检测

  • typeof:返回原始数据类型
  • instanceof:检测构造函数的prototype属性是否出现在某个实例对象的原型链上

String

将其他数值转换为字符串有三种方式:toString()、String()、
拼串。
String 对象属性
constructor 对创建该对象的函数的引用
length 字符串的长度
prototype 允许您向对象添加属性和方法

String.toUpperCase .toLowerCase
.trim():删除字符串左右的空白字符
stringObject.charAt(index)
.charAt(i):获取第i个字符
stringObject.indexOf(searchvalue,fromindex)
.indexOf('i'):获取字符i的位置
.indexOf('o',2):从第2个字符开始搜索o的位置
.lastIndexOf('i'):从结尾搜索字符串位置
stringObject.match(searchvalue)
stringObject.match(regexp)
stringObject.search(regexp)
.search("com"):搜索子字符串"com"的位置
.includes('i'):判断字符串中是否包含i
.startsWith('h'):判断字符串是否为h开头
.endsWith('com'):判断字符串是否为com结束
stringObject.replace(regexp/substr,replacement)
.replace("i","j"):用j替换i
.split(""):将字符串中的每个字符以""分隔
stringObject.split(separator,howmany)
.split(","):将字符串转换为数组
.toString():转换为字符串

截取字符串:slice,substr,substring

stringObject.slice(start,end)允许负数作为参数
stringObject.substr(start,length)
stringObject.substring(start,stop)
slice(i),substr(i),substring(i): 从第i个开始截取
console.log(hd.slice(3)); //dunren.com
console.log(hd.substr(3)); //dunren.com
console.log(hd.substring(3)); //dunren.com
slice(i,j),substring(i,j):截取第i到第j个
substr(i,j)从第i个开始截取,共截取j个字符
console.log(hd.slice(3, 6)); //dun
console.log(hd.substring(3, 6)); //dun
console.log(hd.substring(3, 0)); //hou 较小的做为起始位置
console.log(hd.substr(3, 6)); //dunren

Number

把非数值转换为数值:Number()、parseInt()
和parseFloat()。parseInt()只会将字符串转换为整数,而parseFloat()可以转换
为浮点数。

Number.isInteger(i):判断是否为整数
Number.isNaN(i):判断是否NAN
parseInt(' 99hj'):提取字符串中数字
Math.max.apply(Math, [1, 2, 3]):在数组中取最大值
Math.ceil(1.11):取最接近的向上整数
Math.floor(1.11):取最接近的向下整数
Math.round(1.11):四舍五入
Math.random()*5:返回0-5的随机数,不包括5
Math.random()*(5+1):返回0-5的随机数,包括5
min+Math.floor(Math.random()*(Max-min)):取min-max的随机数

Array

Array 对象属性
constructor 返回对创建此对象的数组函数的引用。
length 设置或返回数组中元素的数目。
prototype 使您有能力向对象添加属性和方法。

Array.isArray([]):检测是否为数组类型
([1,2,3]).toString():转换为字符串1,2,3
([1,2,3]).join("-"):转换为字符串1-2-3
Array.from(str):将类数组转换为数组
...将数组展开,可用于合并数组
.push('1'):压入新元素1,返回值为数组元素数量
.pop():弹出末尾元素,返回值为被弹出的元素
.shift():从数组前面取出元素,返回值为被取出的元素
.unshift():从数组前面添加元素,返回值为数组元素数量
.fill("a"):使用a填充数组元素
arrayObject.slice(start,end) start必需
.slice():获取数组所有元素
.slice(12):从数组中截取1-2的元素合成新元素
arrayObject.splice(index,howmany,item1,.....,itemX) index,howmany必需
.splice(1,3):从第一个元素开始删,一共删3个元素,返回值为被删除的元素
.splice(1,3,'rr'):删掉从第一个开始的三个元素,在删除位置添加rr
.splice(arr.length,0,'kk'):在末尾添加kk
.splice(0,0,'k'):在开头添加k

合并拆分

.join('-'):使用-连接数组内元素为字符串
.split(","):使用,将字符串分割数组
.concat(a,b):连接数组a和b
.copyWithin(target,start,end)

查找元素

.indexOf(i):返回i出现的位置
.lastIndexOf(i):从后向前找
.includes(i):返回布尔值
.find(i):返回第一次找到的值,若找不到则返回undefined,可以查找引用类型
.findIndex(i):返回索引值

数组排序

.reverse():反转
Array.sort((a,b)=>a-b):返回负数则a排在b前面,从小到大

循环遍历

.forEach(item,index,array)
for i in array 每次循环取索引i
for item of array 每次循环取值
for(const [key,value] of array.entries())遍历获取索引和值
arr.keys():获取索引
arr.values():获取值
arr.entries():获取键值对

扩展方法

.every(user => user.js >= 60):递归检测元素,所有都为真才返回true
.some(function (item, index, array) {
	return title.indexOf(item) >= 0;
}):有一个为真就返回true
.filter(function (item, index, array) {
  if (item.category.toLowerCase() == 'css') {
    return true;
  }
}):过滤数据中元素
.map(item => item.title):在数组的所有元素上应用函数,用于映射出新的值
.reduce:迭代数组的所有元素
第一个参数是执行函数,第二个参数为初始值
arr.reduce((previousValue, currentValue, currentIndex, array) => {}, initialValue?)
reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前元素值,当前索引,调用 reduce 的数组。
callback (执行数组中每个值的函数,包含四个参数)
    1、previousValue (上一次调用回调返回的值,或者是提供的初始值(initialValue))
    2、currentValue (数组中当前被处理的元素)
    3、index (当前元素在数组中的索引)
    4、array (调用 reduce 的数组)
initialValue (作为第一次调用 callback 的第一个参数。)
参数	说明
prev	上次调用回调函数返回的结果
cur	当前的元素值
index	当前的索引
array	原数组
array.reduce((total, cur) => (total += cur == elem ? 1 : 0), 0);
}统计元素出现的次数
 array.reduce(
  	(max, elem) => (max > elem ? max : elem), array[0]
  );取数组中的最大值
 array.reduce((goods, elem) => {
    if (elem.price > price) {
      goods.push(elem);
    }
    return goods;
  }, []).map(elem => elem.name);获取价格超过1万的商品名称
  arr.reduce((pre, cur, index, array) => {
  if (pre.includes(cur) === false) {
      pre = [...pre, cur];
  }
  return pre;
}, []) 使用 reduce 实现数组去重

/**
 * 用数组的reduce方法实现数组的map
 */
Array.prototype._map = function(fn, thisArg) {
  const result = [];
  this.reduce((prev, curr, index, array) => {
    result[index] = fn.call(thisArg, array[index], index, array);
  }, 0)
  return result;

Set

移除Set中大于5的数值

let hd = new Set("123456789");
hd=new Set([...hd].filter(item=>item<5))

去除字符串重复

console.log([...new Set("hdsiss")].join(""));

去除数组重复

console.log(...new Set(arr));

交集

let hd = new Set(['hdcms', 'houdunren']);
let cms = new Set(['后盾人', 'hdcms']);
let newSet=new Set(
[...hd].filter(item=>cms.has(item)));
let newSet=[...hds,...cms];求并集

WeakSet结构同样不会存储重复的值,它的成员必须只能是对象类型的值。是弱引用

WeakMap 对象是一组键/值对的集
键名必须是对象
WeaMap对键名是弱引用的,键值是正常引用

函数

如何调用(执行)函数?

  • test()
  • new test()
  • obj.test()
  • test.call/apply(obj)

标准声明优先级高于赋值声明

function hd(num) {
  return ++num;
} 优先级更高,console.log(hd(3))4
var hd = function() {
  return "hd";变量函数定义不会被提升
};

默认参数

function avg(total, year = 1) {
  return Math.round(total / year);
}
console.log(avg(2000, 3));
当不传递year参数时,year的取值为默认值1

arguments 是函数获得到所有参数集合

function sum() {
  return [...arguments].reduce((total, num) => {
    return (total += num);
  }, 0);
}

展开语法

let [a, b, c] = [...hd];
function hd(...args) {
  console.log(args);
}
使用 ... 可以接受传入的多个参数合并为数组

构造函数主要用来生成对象,里面的this默认就是指当前对象
使用箭头函数后 this 为定义该函数的上下文,也可以理解为定义时父作用域中的this. this 总是指向调用该函数的对象

改变构造函数中的空对象,即让构造函数this指向到另一个对象

  • call与apply 用于显示的设置函数的上下文,两个方法作用一样都是将对象绑定到this,只是在传递参数上有所不同。
  • bind()是将函数绑定到某个对象,bind是复制函数行为比如 a.bind(hd) 可以理解为将a函数绑定到hd对象上即
    hd.a(),使用bind会生成新函数
  • apply 用数组传参call 需要分别传参
  • call/apply 会立即执行函数,bind不会立即执行

call()和apply()都可以指定一个函数的运行环境对象,就是设置函数执行时的this值

– 函数对象.call(this对象,参数数组)
– 函数对象.apply(this对象,参数1,参数2,参数N)

常见的回调函数

  1. DOM事件函数
 var btn = document.getElementById('btn')
  btn.onclick = function () {
    alert(this.innerHTML)
  }
  1. 定时器函数
setInterval(function () {
    alert('到点啦!')
  }, 2000)
  1. ajax回调函数
  2. 生命周期回调函数

作用域

子函数被外部使用父级环境将被保留
使用 let/const 可以将变量声明在块作用域中, 在 for 循环中使用let/const 会在每一次迭代中重新生成不同的变量
JS中的所有函数都是闭包
闭包一般在子函数本身作用域以外执行,即延伸作用域
闭包特性中上级作用域会为函数保存数据,从而造成内存泄漏问题
使用箭头函数可以解决函数因为是在全局环境下调用的,所以this指向window的问题

对象

创建对象有两种方式:

var person = new Object();
person.name = "孙悟空";
person.age = 18;
var person = {
name:"孙悟空",
age:18
};

访问属性的两种方式:
.访问 对象.属性名
[]访问 对象[‘属性名’]
什么时候必须使用[‘属性名’]的方式?

  • 属性名不是合法的标识名
  • 属性名不确定

Object.keys 返回一个所有元素为字符串的数组,其元素来自于从给定的object上面可直接枚举的属性。这些属性的顺序与手动遍历该对象属性时的一致

定义在对象中的函数我们称为方法
使用…可以展示对象的结构
对象转换:如果声明需要字符串类型,调用顺序为 toString > valueOf 如果场景需要数值类型,调用顺序为 valueOf > toString
属性管理
hasOwnProperty检测对象自身是否包含指定的属性,不检测原型链上继承的属性

let obj = { name: '后盾人'};
console.log(obj.hasOwnProperty('name')); //true

使用 in 可以在原型对象上检测

console.log(arr.hasOwnProperty("length")); //true
console.log(arr.hasOwnProperty("concat")); //false
console.log("concat" in arr); //true

Object.assign设置属性
使用for/in遍历对象属性
for/of用于遍历迭代对象
同时获取属性名与值

for (const array of Object.entries(hd)) {
  console.log(array);
}

Object.assign 函数可简单的实现浅拷贝,它是将两个对象的属性叠加后面对象属性会覆盖前面对象同名属性。
代理(拦截器)是对象的访问控制,setter/getter 是对单个对象属性的控制,而代理是对整个对象的控制
使用 JSON.parse 将字符串 json 解析成对象

原型

在构造函数中存在着一个名为原型的(prototype)对象,这个对象中保存着一些属性,凡是通过该构造函数创建的对象都可以访问存在于原型中的属性

每个函数都有一个prototype属性, 它默认指向一个对象原型对象
每个函数都有一个prototype属性, 它默认指向一个对象原型对象,原型对象中有一个属性constructor, 它指向函数对象
原型对象中有一个属性constructor, 它指向函数对象

  console.log(Date.prototype.constructor===Date) true
  console.log(fn.prototype.constructor===fn) true
  1. 每个函数function都有一个prototype,即显式原型
  2. 每个实例对象都有一个__proto__,可称为隐式原型
  3. 对象的隐式原型的值为其对应构造函数的显式原型的值
  • 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象
  • 对象的__proto__属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值
function Fn() {
  }
  var fn = new Fn()
  console.log(Fn.prototype, fn.__proto__)
  console.log(Fn.prototype===fn.__proto__)
VM901:5 {constructor: ƒ} {constructor: ƒ}
VM901:6 true

程序员能直接操作显式原型

Fn.prototype.test = function () {
    console.log('test()')
  }
  fn.test() test()

获取原型对象
– 构造函数. prototype
– Object.getPrototypeOf(对象)
– 对象._ proto_
– 对象. constructor.prototype

原型链 别名: 隐式原型链 作用: 查找对象的属性(方法)

每个对象都有原型对象,原型对象也有原型对象。对象,和对象的原型,以及原型的原型,就构成了一个原型链
当从一个对象中获取属性时,会首先从当前对象属性中查找,如果没有则顺着__proto__查找,直到找到Object对象的原型位置,找到则返回,找不到则返回undefined。

读取对象的属性值时: 会自动到原型链中查找
设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  Person.prototype.setName = function (name) {
    this.name = name; 方法一般定义在原型中
  }
  Person.prototype.sex = '男';  属性一般通过构造函数定义在对象本身上

原型是一个指向对象的指针,可以将原型理解为对象的父亲,对象从原型对象继承来属性.使用原型对象为多个对象共享属性或方法
原型包含 constructor 属性,指向构造函数
对象包含 __proto__ 指向他的原型对象
使用原型可以解决,通过构建函数创建对象时复制多个函数造成的内存占用问题
函数拥有多个原型,prototype 用于实例对象使用,__proto__用于函数对象使用

function User() {}
User.__proto__.view = function() {
  console.log("User function view method");
};
User.view();

User.prototype.show = function() {
  console.log("后盾人");
};
let hd = new User();
hd.show();
console.log(User.prototype == hd.__proto__);

创建对象时构造函数把原型赋予对象
在这里插入图片描述

function User() {}
let xj = new User();
console.log(xj.__proto__ == User.prototype);

表达式: A instanceof B

  • 如果B函数的显式原型对象在A对象的原型链上, 返回true, 否则返回false
    Function是通过new自己产生的实例
function Foo() {  }
  var f1 = new Foo();
  console.log(f1 instanceof Foo); true
  console.log(f1 instanceof Object); true

使用 setPrototypeOf 与 getPrototypeOf 设置和获取原型
constructor存在于prototype原型中,用于指向构建函数的引用

instanceof 检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
使用isPrototypeOf检测一个对象是否是另一个对象的原型链中
使用in 检测原型链上是否存在属性,使用 hasOwnProperty 只检测当前对象
使用 for/in 遍历时同时会遍历原型上的属性
使用 call 或 apply 可以借用其他原型方法完成功能

let hd = {
  data: [1, 2, 3, 4, 5]
};
Object.setPrototypeOf(hd, {
  max: function() {
    return this.data.sort((a, b) => b - a)[0];
  }
});
console.log(hd.max());

let xj = {
  lessons: { js: 100, php: 78, node: 78, linux: 125 },
  get data() {
    return Object.values(this.lessons);
  }
};
console.log(hd.__proto__.max.apply(xj));

this 不受原型继承影响,this 指向调用属性时使用的对象

let hd = {
  name: "后盾人"
};
let houdunren = {
  name: "向军",
  show() {
    return this.name;
  }
};
hd.__proto__ = houdunren;
console.log(hd.show());后盾人

函数默认prototype 指包含一个属性 constructor 的对象,constructor 指向当前构造函数
使用Object.create创建一个新对象时使用现有对象做为新对象的原型对象
在实例化对象上存在 __proto__ 记录了原型,所以可以通过对象访问到原型的属性或方法

__proto__ 不是对象属性,理解为prototype 的 getter/setter 实现,他是一个非标准定义
__proto__ 内部使用getter/setter 控制值,所以只允许对象或null
建议使用 Object.setPrototypeOf 与Object.getProttoeypOf 替代 __proto__
使用 in 会检测原型与对象,而 hasOwnProperty 只检测对象,所以结合后可判断属性是否在原型中

function User() {
}
User.prototype.name = "后盾人";
const lisi = new User();
//in会在原型中检测
console.log("name" in lisi);true
//hasOwnProperty 检测对象属性
console.log(lisi.hasOwnProperty("name"));false

使用 prototype 更改构造函数原型,使用 Object.setPrototypeOf 与 Object.getPrototypeOf 获取或设置原型。
Object.create 创建对象时指定原型
__proto__ 声明自定义的非标准属性设置原型,解决之前通过 Object.create 定义原型,而没提供获取方法
Object.setPrototypeOf 设置对象原型

构造函数在被new 时把构造函数的原型(prototype)赋值给新对象。如果对象中存在属性将使用对象属性,不再原型上查找方法
当对象中没有可以使用的属性时,JS会从原型上获取这就是继承在JavaScript中的实现

通过构造函数创建对象

function Admin() {}
console.log(Admin == Admin.prototype.constructor); //true

let hd = new Admin.prototype.constructor();
console.log(hd);

let xj = new Admin();
console.log(xj);

多态
根据多种不同的形态产生不同的结果,下而会根据不同形态的对象得到了不同的结果
继承是为了复用代码,继承的本质是将原型指向到另一个对象
JS不能实现多继承,如果要使用多个类的方法时可以使用mixin混合模式来完成。
使用 isPrototypeOf 判断一个对象是否在另一个对象的原型链中

正则表达式

直接量语法
/pattern/attributes
创建 RegExp 对象的语法:
new RegExp(pattern, attributes);
/正则表达式/修饰符(可选)
参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数 attributes 是一个可选的字符串,包含属性 “g”、“i” 和 “m”,分别用于指定全局匹配、区分大小写的匹配和多行匹配。

  • 修饰符:i(执行大小写不敏感的匹配), g(全局匹配), m(多行匹配)

  • [] 只匹配其中的一个原子
    [^] 只匹配"除了"其中字符的任意一个原子
    [0-9] 匹配0-9任何一个数字
    [a-z] 匹配小写a-z任何一个字母

  • \d(查找数字),\s(查找空白字符),\b(匹配单词边界) n+(匹配至少包含一个n的字符串),
    n*(包含零或多个n的字符串),n?(包含零或一个的字符

  • ^ 匹配字符串的开始 $ 匹配字符串的结束,忽略换行符

  • /是正则表达式开始和结束的标志,\将后面的字符标记为特殊字符

    <p>替换"k1""k2"</p>
    <button onclick="f1()">Click me</button>
    <p id="demo">请访问k1</p>
<script>
function f1(){
  var str=document.getElementById("demo").innerHTML;
  var txt=str.replace("k1","k2");
  document.getElementById("demo").innerHTML= txt;}
</script>

使用${}实现变量和字符串的拼接

if(window.confirm(`hello${this.name}`))

创建数组

     var i;
     var cars=new Array();
     cars[0]="a";
     cars[1]="b";
     cars[2]="c";
     for(i=0;i<cars.length;i++)
     document.write(cars[i]+"<br>");

创建对象

     var people=new Object();
     people.name='Tim';
     people.age=17;
     people.eat=function(){}

添加删除数组项

  • 作用在数组末尾:push()/pop() 调用后返回数组新长度/返回已被删除的部分
  • 作用在数组开头:unshift(),shift()

字符串方法
charAt(), concat(), indexOf(), lastIndexOf(), localeCompare(), match(),split(), splice(), substr(), substring(), toString(), tpUpperCase(),
trim(), valueOf()

DOM

选取节点
节点:Node——构成HTML文档最基本的单元。
• 常用节点分为四类
– 文档节点document:整个HTML文档
– 元素节点Element:HTML文档中的HTML标签
– 属性节点Attr:元素的属性
– 文本节点Text:HTML标签中的文本内容
获取元素节点• 通过document对象调用

1. getElementById()
– 通过id属性获取一个元素节点对象
2. getElementsByTagName()
– 通过标签名获取一组元素节点对象
3. getElementsByName()
– 通过name属性获取一组元素节点对象

获取元素节点的子节点 • 通过具体的元素节点调用

1. getElementsByTagName()
– 方法,返回当前节点的指定标签名后代节点
2. childNodes
– 属性,表示当前节点的所有子节点
3. firstChild
– 属性,表示当前节点的第一个子节点
4. lastChild
– 属性,表示当前节点的最后一个子节点

获取父节点和兄弟节点 • 通过具体的节点调用

1. parentNode
– 属性,表示当前节点的父节点
2. previousSibling
– 属性,表示当前节点的前一个兄弟节点
3. nextSibling
– 属性,表示当前节点的后一个兄弟节点

属性
• nodeValue
– 文本节点可以通过nodeValue属性获取和设置文本节点的内容
• innerHTML
– 元素节点通过该属性获取和设置标签内部的html代码

使用CSS选择器进行查询

querySelector()  querySelectorAll()

• 都是用document对象来调用,都是传递一个选择器字符串作为参数,方法会自动根据选择器字符串去网页中查找元素。
• querySelector()只会返回找到的第一个元素,而querySelectorAll()会返回所有符合条件的元素。

document.getElementById(id)
getElementByName('name') 获取设置了name属性的元素
getElementsByTagName用于按标签名获取元素
getElementsByClassName用于按class 样式属性值获取元素集合
querySelectorAll根据CSS选择器获取Nodelist节点列表
querySelector使用CSS选择器获取一个元素
 const app = document.getElementById('app')
  const nodes = [...app.querySelectorAll('li')].filter((node) => {
    return !node.matches(`[name]`)
  })
  console.log(nodes)

使用getElement…返回的都是HTMLCollection动态的集合
使用querySelectorAll返回的是NodeList静态集合

节点的修改

指对元素节点的操作

• 创建节点
– document.createElement(标签名)
• 删除节点
– 父节点.removeChild(子节点)
• 替换节点
– 父节点.replaceChild(新节点 , 旧节点)
• 插入节点
– 父节点.appendChild(子节点)
– 父节点.insertBefore(新节点 , 旧节点)

显示数据

  • window.alert()弹出窗口
  • document.write()将内容写入HTML文档中
document.write(Date());
  • innerHTML写入HTML元素中
<p id="a">k</p>
<script>
document.getElementById("a").innerHTML="kkk";
</script>
  • console.log()将内容写入控制台

JavaScript计算器


```javascript
<table border="1" style="position: center ;">
<tr><td>第一个数</td><td>
  <input type="text" id="first" /></td></tr>
<tr><td>第二个数</td>
<td><input type="text" id="second" /></td> </tr>
  <tr><td colspan="2">
    <button onclick="sum()">+</button>
    <button onclick="substract()">-</button>
    <button onclick="f()">*</button>
    <button onclick="divide()">/</button></td></tr>
<tr><td colspan="2">
   <p id="result">结果是:</p> </td></tr>
</table>
    <script>
      function getFirst(){
        var f=document.getElementById("first").value;
        return f;
      }
      function getSecond(){
        var s=document.getElementById("second").value;
        return s;
      }
      function sendResult(r){ // 给p标签传值
      var n=document.getElementById("result");
      n.innerHTML=r;
      }
function sum()
{
  var a=getFirst();
  var b=getSecond();
  var r=Number(a)+Number(b); // 不转换为数字的话结果就是两个字符串的连接
  sendResult(r);
}
function substract()
{
  var a=getFirst();
  var b=getSecond();
  var r=a-b;
  sendResult(r);
}
    </script>
全选/全不选

```javascript
1<input type="checkbox" name="c" value=1/><br>
2<input type="checkbox" name="c" value=2/><br>
3<input type="checkbox" name="c" value=3/><br>
4<input type="checkbox" name="c" value=4/>
<input type="button" value="全选" onclick="allcheck(this)"/>
    <script>
     var checkAll=false;
     function allcheck(e)
     {
       checkAll=!checkAll;
       e.value=checkAll ? "全选" : "全不选";
       let inputs=document.getElementsByName('c');
       for(var index in inputs)
       inputs[index].checked=checkAll;

     }

JavaScript表单验证

验证输入

<p>请输入1-10的数字</p>
   <input id="num" />
   <button onclick="check()">提交</button>
   <p id="demo"></p>
<script>
function check(){
  var x,text;
  x=document.getElementById("num").value;
  if(isNaN(x)||x<1||x>10)
    text="输入错误";
  else text="输入正确";
  document.getElementById("demo").innerHTML=text;
}
</script>

this 的多种指向:

1、在对象方法中, this 指向调用它所在方法的对象。
2、单独使用 this,它指向全局(Global)对象。
3、函数使用中,this 指向函数的所属者。
4、严格模式下函数是没有绑定到 this 上,这时候 this 是 undefined。
5、在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素。
6、apply 和 call 允许切换函数执行的上下文环境(context),即 this 绑定的对象,可以将 this 引用到任何对象。

事件

为一个元素绑定事件处理程序:
– 通过HTML元素指定事件属性来绑定
– 通过DOM对象指定的属性来绑定
– 设置事件监听器 元素对象.addEventListener() 需要两个参数:事件字符串,响应函数

事件的传播
• 捕获阶段
– 这一阶段会从window对象开始向下一直遍历到目标对象,如果发现有对
象绑定了响应事件则做相应的处理。
• 目标阶段
– 这一阶段已经遍历结束,则会执行目标对象上绑定的响应函数。
• 事件冒泡阶段
– 这一阶段,事件的传播方式和捕获阶段正好相反,会从事件目标一直向
上遍历,直至window对象结束,这时对象上绑定的响应函数也会执行。
取消事件传播
• 可以使用event对象的两个方法完成:
– stopPropagation()
– stopImmediatePropagation()
• 取消默认行为:
– preventDefault()
HTML事件:onchange, onclick, onload, onmouseover, onkeydown
改变HTML:

  • document.write() // 改变输出流
  • document.getElementById(id).innerHTML=新HTML // 改变HTML元素内容
  • document.getElementById(id).attribute=新属性值 // 改变HTML元素属性

改变CSS:

  • document.getElementById(id).style.property=新样式

HTML事件属性

  • 向HTML元素分配事件
<Button onclick="displayDate()">Click me</Button>
  • 使用HTML DOM分配事件
<script>document.getElementById("bst").onclick=function(){ displayDate();}}</script>

EventListener

Element.addEventListener(event, function);
event:事件类型,如click/mousedown,
function:事件触发后调用的函数,

element.addEventListener("mouseover", myFunction);
element.addEventListener("click", mySecondFunction);
element.addEventListener("mouseout", myThirdFunction);

x=document.getElementById(id)为null导致addEventListener无法使用时,可加上window.onload

window.onload = function () {
    var x = document.getElementById("myBt");
    x.addEventListener("click", myFunction);
};

JavaScript HTML DOM 元素

  • appendChild() // 创建新的HTML节点
<div id="d">
<p id="p1">p1</p></div>
<script>
var para=document.createElement("p"); // 创建<p>元素
var node=document.createTextNode("p'");// 为<p>元素创建一个新的文本节点
para.appendChild(node); // 将该文本节点添加到<p>元素中
var e=document.getElementById("d"); // 查找已存在的元素
e.appendChild(para); // 将<p>元素添加到该元素中
    </script>
  • 将新元素添加到开始位置处:insertBefore()
  • 移除已存在的元素,需知道其父元素 parent.removeChild(child)
  • 替换 HTML 元素 - replaceChild()
<div id="d">
<p id="p1">p1</p>
<p id="p2">p2</p></div>
<script>
var para=document.createElement("p");
var node=document.createTextNode("p3");
para.appendChild(node);
var parent=document.getElementById("d");
var child=document.getElementById("p1");
parent.replaceChild(para, child); // 用p3的值替换p1的值
    </script>

闭包

闭包是一个函数引用另一个函数的变量,提供了一个在外部访问另一个函数内部局部变量的方式,不必要的闭包只会增加内存消耗。
设置计数器递增:

<p>局部变量计数</p>
   <button onclick="f1()">计数</button>
   <p id="p">0</p>
<script>
  var add =(function(){
    var count=0; // 从外部访问该局部变量count,保证其递增
    return function(){
      return count+=1;
      }
  })();
  function f1(){
    document.getElementById("p").innerHTML=add();
  }
</script>

BOM(浏览器对象模型)

超时调用
– setTimeout()
– 超过一定时间以后执行指定函数
– 需要连个参数:
• 要执行的内容
• 超过的时间
• 取消超时调用
– clearTimeout()
• 超时调用都是在全局作用域中执行的。
间歇调用
• 间歇调用:
– setInterval()
– 每隔一段时间执行指定代码
– 需要两个参数:
• 要执行的代码
• 间隔的时间
• 取消间隔调用:
– clearInterval()
弹窗

  • 警告框:window.alert(“text”);
  • 确认框:window.confirm(“text”);
  • 提示框:window.prompt(“text”,“defaultvalue”);

Promise

Promise 将异步操作队列化,按照期望的顺序执行,返回符合预期的结果。一个 promise 必须有一个 then 方法用于处理状态改变

Promise包含pending、fulfilled、rejected三种状态

  • pending 指初始等待状态,初始化 promise 时的状态
  • resolve 指已经解决,将 promise 状态设置为fulfilled
  • reject 指拒绝处理,将 promise 状态设置为rejected
  • promise 是生产者,通过 resolve 与 reject 函数告之结果
  • promise 创建时即立即执行即同步任务,then 会放在异步微任务中执行,需要等同步任务执行后才执行。then是对返回promise的处理

如果 resolve 参数是一个 promise ,将会改变promise状态.当promise做为参数传递时,需要等待promise执行完才可以继承
链式调用
每次的 then 都是一个全新的 promise,默认 then 返回的 promise 状态是 fulfilled
catch用于失败状态的处理函数,等同于 then(null,reject){}
扩展接口

  • resolve 使用 promise.resolve 方法可以快速的返回一个promise对象
  • reject 生成一个失败的promise
  • 使用Promise.all 方法可以同时执行多个并行异步操作
  • allSettled 用于处理多个promise ,只关注执行完成,不关注是否全部执行成功,allSettled 状态只会是fulfilled
  • 使用Promise.race() 处理容错异步,和race单词一样哪个Promise快用哪个,哪个先返回用哪个

任务管理

宏任务指执行栈中待执行的任务(主线程上的同步任务), 包括 script(整体代码)、setTimeout、setInterval
微任务指当前任务执行之后立即执行的任务, 包括 Promise.then
任务的执行顺序是同步任务、微任务、宏任务
事件运行机制
执行一个宏任务;
遇到微任务,放到微任务列队;
宏任务执行完毕,执行微任务列队中的任务;
微任务执行完毕后,GUI 线程接管,开始渲染页面;
渲染完成后,JS线程继续接管,开启下一个宏任务

Promise 内的任务为立即执行任务,也可以理解为同步任务。而 then 方法中的任务是微任务,会放在微任务列表中

setTimeout(() => console.log(4));
new Promise(resolve => {
  resolve();
  console.log(1);
}).then(_ => {
  console.log(3);
});
console.log(2);
1 2 3 4

Promise.then 是典型的微任务,实例化 Promise 时执行的代码是同步的,便then注册的回调函数是异步微任务的。主线程中的任务执行完后,才执行队列中的任务。有新任务到来时会将其放入队列,采取先进先执行的策略执行队列中的任务

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值