javascript笔记

javaScript(区分大小写)

ECMAScript定义了javascript的规范,javascriptECMAScript的一种实现完整的javascript包含ECMAScriptDOMBOM

js的引入

​ 页面中插入:<script></script>
​ 外部引入:

<!-- 同步下载,会阻塞文档解析 -->
<script src="url"></script>
<!-- async 异步下载,下载完成立即执行脚本代码,不影响其他资源加载 -->
<script src="url" async="async"></script>
<!-- defer 异步下载,延迟执行 文档完全解析和显示之后才会执行脚本 -->
<script src="url" defer="defer"></script>

在这里插入图片描述

不管是内部<script></script>还是外部<script src="XXX"/>,都是按照代码在页面位置的顺序依次执行,且后面的script标签中可以使用前面script中的值,一个script标签执行完毕后才会执行后面的代码,除非在外部引入的时候使用asyncdefer来改变执行时机

<!-- 在浏览器不支持js或js被禁用时会渲染<noscript></noscript>中的内容 -->
<noscript> 
 	<p>This page requires a JavaScript-enabled browser.</p> 
</noscript>

标识符命名规则

​ 可以用字母、下划线、$、数字,必须以字母或 “_”, $开头

注释

​ 单行注释://
​ 块级注释: /* */
​ html注释: <!-- -->
​ css注释:/* */

变量

关键字 块级作用域 变量提升 重复声明
var 没有 可以重复声明
let 没有 同一作用域不可以重复声明 ,否则会报错
const 没有 同一作用域不可以重复声明 ,否则会报错(声明常量,不能重新赋值)

​ 通过var声明的全局变量或方法会挂载到window上,letconst声明的不会

五种基本数据类型

typeof: 是一个操作符不是函数,用来检测数据类型,nullobjectundefinedundefined
undefined: 表示变量声明过但并未赋过值。
null:表示一个空对象指针,将来可能指向一个对象 ,用于释放对象的引用
Boolean: 布尔值
(0,-0,"",null,undefined,NaN, false)布尔值为false外,其他布尔值都为true
number: 数值类型
Number对象: https://www.runoob.com/jsref/jsref-obj-number.html

浮点数  float
无穷大: Number.MAX_VALUE, 无穷小: Number.MIN_VALUE
数值范围  isFinite() // 检测参数是否为无穷数,返回boolean值,NaN、Infinity、-Infinity为false,其他
非数值  NaN,  isNaN()  // 判断是 “不是一个数值”
//强制转换 常用方法
Number(obj)  // 将对象转换为数字,若无法转换则返回NaN, ""和null,false转换为0,undefined转换为NaN
parseInt(string,radix)   // 将字符串转换为整数数值,""转换为NaN。会省略掉小数点后无意义的0
parseFloat(string)  // 将字符串转换为浮点数

// Number对象常用方法。
// 注意点:不能在数字后面直接跟方法,因为浏览器不识别数字后面的'.'是小数点还是运算符。
// 3.toString()这种写法会报错
num.toString() // 没有参数,将数值型转换为字符串。会省略掉小数点后无意义的0
num.toFixed()	// 一个参数 保留几位小数(四舍五入),返回结果为字符串
num.toExponential()	// 一个参数 返回值以几位数返回,以科学计数法返回,返回结果为字符串
num.toPrecision() // 一个参数 返回值以几位数返回,以更精确的格式返回结果,根据参数决定调用toFixed()还是toExponential(),返回结果为字符串

string: 字符串类型
​ String对象:https://www.runoob.com/jsref/jsref-obj-string.html
​ es6字符串:https://www.runoob.com/w3cnote/es6-string.html

//强制转换 常用方法
obj.toString() // 没有参数,null与undefined没有toString()方法
String(obj)   // 任何类型都可以使用String()方法

// 补零的两种方法
// 方法一
num < 10 ? '0' + num : num;
// String对象串常用方法 
toUpperCase()			// 将字符串转换为大写 不改变原字符
toLowerCase()			// 将字符串转换为小写 不改变原字符
str.slice(start,end) 	// 截取字符串	返回截取的新字符串
str.substr(start,length) //	截取字符串	返回截取的新字符串
str.substring(start,end)	// 截取字符串	返回截取的新字符串
str.split('分隔符')	// 字符串转数组 参数为分隔符,不改变原始字符串。 返回数组
str.replace(searchvalue,newvalue)  // 返回一个新的字符串  不改变原字符串
str.charAt(index)	// 返回指定位置的字符 索引从0开始,最后一个字符索引(str.length-1)value
str.indexOf(searchValue,start)	//	返回指定字符在字符串中首次出现的位置,start开始查找位置 可选,未找到返回-1
string.concat(string1, string2, ..., stringX)	// 拼接多个字符串 没有改变原字符串 返回新字符串
// 它可以用于检索字符串中是否包含一个指定的字符或者子字符串
// 其中regexp可以是一个正则表达式对象或者一个字符串,当regexp是一个字符串时,会被隐式地转换成正则表达式对象,如果没有匹配结果,则返回null。
str.match(regexp) 

String新增实例方法

// es6新增字符串拼接方法
var str = `今年是${
     years}`;
str.trim()  // 去除字符串首尾两端的空格 不改变原字符
trimLeft(), trimRight()	// 清除左边或右边空格

let str = `!zhangsan`;
//startsWith(str): 检测参数字符串是否在原字符串的头部,返回布尔值
console.log(str.startsWith("zhan"));    // false
//endsWith(str): 检测参数字符串是否在原字符串的尾部,返回布尔值
console.log(str.endsWith("san")); // true
// includes(str): 检测参数字符串是否在原字符串中,返回布尔值
console.log(str.includes("q"));  // false
// repeat(n): 表示将原字符串重复n次,返回新字符串
console.log(str.repeat(2));     // !zhangsan!zhangsan
// padStart("填充后的长度","用来填充的字符"): 在原字符串的前面填充,默认用空格填充,返回修改后的新字符串,不改变原字符串
console.log(str.padStart(10,'0'));  // 0!zhangsan
// padEnd("填充后的长度","用来填充的字符"): 在原字符串的后面填充,返回修改后的新字符串,不改变原字符串
console.log(str.padEnd(10,'0'));    // !zhangsan0

操作符

一元操作符

--a, ++a,a--,a++ 等等,前置是先计算后返回值,后置是先返回值再计算
--, ++ // 有隐式转换的功能,类似于Number()

算数运算符

//乘性操作符
*, /, %  会触发Number()的隐式转换
//加性操作符
+ : 会触发toString()的隐式转换
- : 会触发Number()的隐式转换

关系运算符(返回的是Boolean值)

// >, <, >=, <=
任何值和NaN比较结果都是false
两个都是字符串比较时,不会隐式转换(即使是纯数字的字符串),比较对应位置上每个字符的字符编码值
一个数值和一个字符串比较时,字符串会触发Number()隐式转换为数值

相等运算符

等于(==),不等于(!=),全等(===),不全等(!==)

逻辑运算符

//**布尔操作符**
// 布尔操作符:与(and),或(or),非(not),进行布尔值运算的运算符,其返回值也是布尔值
!a :逻辑非,取反 返回布尔值
!!a : 两次取反返回a的真正布尔值
// 短路运算(逻辑中断)
// 当有多个表达式(值)时,左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值
a && b :逻辑与,若a为false,则不再继续判断b,返回a;若a为true,则返回b
a || b :逻辑或,若a为true,则不再继续判断b,返回a;若a为false,则返回b
a = b || c : // 若b为空就将c赋给a

赋值运算符

// 复合赋值操作
+=, -=, *=, /=, %=

条件运算符

// 求num1与num2之间的较大值
var max = (num1 > num2) ? num1 : num2;

逗号操作符

// 一条语句执行多个操作
var num1 = 1, num2 = 2, num3 = 3;
// 用于赋值,返回表达式中最后一项
var num = (2,3,5,1,0)   // num的值为0

在这里插入图片描述

语句

// break 跳出循环或代码块,continue 跳过循环中的一个迭代
// 条件判断语句
if(){
   ...} else{
   ...}
// 三元运算符
表达式1 ? 表达式2 : 表达式3;
// 流程控制语句,a只能是Number或String
switch(a) {
   
	case 1:
		.....;
		break;
	case 2:
		......;
		break;
	default:
		break;
}
// 先执行后判断
do{
   ...} while()
// 先判断后执行              
while(){
   ...} 
// for循环等同于while
for(){
   }
// 循环遍历对象的属性
for(key in object){
   }

if else语句与switch语句的区别
switch语句中只能处理case为常量的情况,if语句使用场景更多
if语句会逐个条件计算,只能执行到满足条件的那一个,而switch语句是直接跳转到满足条件的哪一个,只会计算一次,因此当分支较多时,switch的效率要比if语句高

变量、作用域、内存问题

变量

​ 基本数据类型:按值来访问的,储存在栈内存
​ 引用类型:值是保存在内存中的,不允许直接访问内存中的位置,通过引用访问。储存在堆内存

// 基本类型 变量复制后num1,num2相互独立 互不影响
// 引用类型 变量复制后 只是复制了一个指针,obj1,obj2都指向堆内存中的同一个对象,obj1和obj2其中一个改变会影响另一个
// 基本类型num1,num2
var num1 = 5;
var num2 = num1;
// 引用类型obj1,obj2
var obj1 = new Object();
obj1.name = "zhangsan"
var obj2 = obj1;
obj2.name = "lisi";
alert(obj.name);   // 弹出"lisi"
作用域

每个局部执行环境(上下文)都有一个与之关联的变量对象,该执行环境中所有的变量和函数都存在于这个变量对象上,当代码执行到某个局部执行环境(上下文)时,会创建变量对象的一个作用域链,作用域链可向上追溯到全局变量对象

  • 全局执行环境的变量对象一直存在,局部环境的变量对象只有在函数执行的过程中存在。
  • 通过var声明的全局变量或方法会挂载到window上,letconst声明的不会
  • 任何变量(不管包含的是原始值还是引用值)都存在于某个执行上下文中(也称为作用域)。这个上下文(作用域)决定了变量的生命周期,以及它们可以访问代码的哪些部分。
预解析(变量提升)

通过var声明的变量或函数会有变量提升,而通过letconst声明的不会(看起来不会,实际上也会)

  • 变量提升:变量的声明会被提升到当前作用域的最前面,变量的赋值不会提升
  • 函数提升:函数的声明会被提升到当前作用域的最前面,但不会调用函数

预解析中的一些特殊情况

  • if 语句中不管条件是否成立,都会对语句内部代码进行预解析。
  • ;(function(){})() 立即执行函数不进行预解析,定义和执行一起完成。
  • return 语句后面的代码不执行了,但依然需要预解析,return中的代码都是返回值,不需要预解析

那么为什么var声明的变量会有变量提升,而letconst声明的变量不会有变量提升呢?
var声明的变量会被挂在到running execution context(执行上下文)VariableEnvironment(变量环境)上,会在当前作用域的变量对象实例化的过程中被声明并赋值为undefined。 在赋值语句执行时才会为变量赋值。
letconst声明的变量会被挂在到running execution context(执行上下文)LexicalEnvironment(词法环境)上,会在当前作用域的变量对象实例化的过程中被创建,但是直到变量的语法声明代码被执行之前,他们都是不可被访问的。同样在赋值语句执行时才会为变量赋值。
​ 所以,letconst声明的变量也会变量提升,只是他们在定义的语句执行前不能被访问而已

引用类型

Object类型

对象:一列无序的属性和方法的集合(是一组数据和功能的集合)
hasOwnProperty(propertyName):用于判断当前对象实例(不是原型)上是否存在给定的属性。要检查的属性名必须是字符串(如 obj.hasOwnProperty("name"))或符号。

// 利用关键字new Object()创建
var person = new Object();
person.name = "zhangsan";
person.age = 29;

// 字面量创建法
var person = {
   
    name : "zhangsan",
    age : 29
}

//构造函数方法创建
function Create(name,age) {
   
    this.name = name,
    this.age = age
}
var obj1 = Create(name,age);

// for(let key in obj) { } 遍历数组或对象,通过in操作符会遍历出对象自身属性和原型属性
var obj = {
   name: 'zhangsan', age: 18, sex: '男'}
for(let key in obj){
   }	// for...in 遍历对象、数组、字符串的key

// 访问对象属性可以通过.或者[]访问
obj.name
obj['name']

删除对象属性

const obj = {
   
	name: 'zhangsan',
	age: 28
}

// 方法一,直接删除
delete obj.age

// 方法二,通过Object.defineProperty更改对象属性的配置项
// 没有实际被删除,只是不能被遍历到了,值也改为了undefined
Object.defineProperty(obj, "age", {
   
  value: undefined,
  enumerable: false	// 能否被遍历
});

常用方法

  • 解构赋值{}, 展开运算符...
  • 新增遍历方法:Object.keys(obj), Object.values(obj), Object.entries(obj),新增的三个方法都只会遍历出对象实例自身的属性,不会遍历出原型上的属性,for...in...会遍历出自身和原型上的属性
  • 对象合并方法:Object.assign(obj1,obj2) 返回一个新对象
数组(Array)

https://www.runoob.com/jsref/jsref-obj-array.html
创建数组

// 构造函数创建
var arr = new Array();  
// 字面量创建
var arr = ['red','pink'];   

常用方法

// 检测某一个对象是不是数组
//方法一
if(arr instanceof Array) {
   }
// 方法二
if(Array.isArray(arr)) {
   }

// 数组转字符串,join(separator) 参数为分隔符默认为",".
// 将数组转换为字符串(若其中某项为null或undefined,则以空字符串表示)·
arr.join();
// 数组添加或删除项(会改变原数组)
// 栈方法(先进后出,栈中的堆入和弹出都只发生在栈的顶部)
var arr = [1,2,3]
arr.push(4);	  // push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
arr.pop();        //  pop() 方法用于删除数组的最后一个元素并返回删除的元素。 
// 队列方法(先进先出,队列在列表的末端添加,从列表的前端移除)
arr.shift();    //方法用于把数组的第一个元素从其中删除,并返回删除的元素。
arr.unshift()          // 方法可向数组的开头添加一个或更多元素,并返回新的长度。

array.slice(start, end)		// 截取数组元素,也可截取字符串,不包含结束位置元素,可为负值(相当于数组长度加上这个负值),如果开始位置小于结束位置则返回空数组.返回截取的新数组
[1,2,3,4,5].slice(-4,-1) 	// 相当于 array.slice(1,4)
array.splice(index,howmany,item1,.....,itemX)
// splice():有删除、插入、替换功能,始终返回一个包含删除项的数组(若没有删除项则返回空数组),会改变原始数组。数组塌陷,解决办法采用从最后一项开始倒着循环

// 扩展运算符: 可以将数组或者对象转为用逗号分隔的参数序列
let arr = [1,2,3]
console.log(...arr)		// => 1,2,3
// 拼接数组
 let ary1 = [1, 2, 3];
 let ary2 = [3, 4, 5];
// 方法一 扩展运算符
 let ary3 = [...ary1, ...ary2];
 // 方法二 
 ary1.push(...ary2);
// 方法三
let arr3 = ary1.concat(ary2);

Array.from(str)	// 将类数组转化为数组
Array.of()		// 可以把一组参数转换为数组
console.log(Array.of(1,2,3))	// => [1,2,3]

// forEach遍历数组	改变原数组 没有返回值,return 会跳出当前循环,类似continue
arr1.forEach(function(value,index,arr){
   })

// map 映射,返回一个新数组,对数组中所有元素进行统一操作
const arr2 = [10,20,30,40]
let newArr = arr2.map((value,index,arr)=>{
   return value*2})	// [20,40,60,80]

// filter 过滤 返回一个新数组,遍历数组所有元素 每次遍历必须返回布尔值 为true则将遍历元素添加到返回的新数组中,为false则不添加
const arr3 = [10,20,30,40]
let newArr = arr3.filter((value,index,arr)=>{
   return value>20})	// [30,40]

// array.reduce(function(total, currentValue, currentIndex, arr){}, initialValue)
// 累加器 返回计算结果
const arr = [10,20,30,40]
let total = arr.reduce((preValue,value)=>{
   
    return preValue + value
},0)

// some 一些,用于检测数组中的元素是否满足指定条件 返回布尔值 碰到true就终止遍历
arr4.some(function(value,index,arr){
    return ...})

// every 所有,用于检测数组所有元素是否都符合指定条件 返回布尔值  碰到false就终止遍历
arr5.every(function(value,index,arr){
   })

// find	查找指定数组项,找到则返回数组项  未找到返回undefined
// findIndex 查找指定数组项,找到则返回数组项的索引  未找到返回-1
const arr = []
arr.find(() => {
    return ...})
arr.findIndex(() => {
    return ...})

// includes 查找是否存在某个元素 如果找到返回true 没找到返回false
const arr = []
arr.includes() 
arr.indexOf()	// 找到返回索引值,找不到返回-1
arr.lastIndexOf()	// 从最后一项开始查找

​ 数组重排序及去重

//	冒泡排序
var arr = [5,6,12,1,9];
// 外层循环 比较的轮数
for(var i = 0; i < arr.length -1; i++) {
   
   // 内层循环 每轮比较的次数
   for(var j = 0; j < arr.length - i - 1; j++) {
   
       if(arr[j] < arr[j+1]) {
   
           // 每次满足条件交换位置
           var num = arr[j];
           arr[j] = arr[j+1];
           arr[j+1] = num;
        }
    }
}
console.log(arr);

// 重排序方法
arr.reverse();        // 方法用于颠倒数组中元素的顺序。 改变原数组
array.sort(sortfunction)	// sort() 方法用于对数组的元素进行排序。
// 排序顺序可以是字母或数字,并按升序或降序。
var arr = [0,1,15,5];
// 数组冒泡排列
arr.sort(compare);   // 改变原数组
function compare(value1,value2) {
   
    // 升序
    return value1 - value2;
    // 降序
    // return value2 - value1;
    // 乱序排列
    // return Math.random() - 0.5;
}

数组去重

// 简单数组去重
let arr1 = [2,4,'a','a',2]
let newArr = new Set(arr1)
// 复杂数组去重
let arr1 = [{
   ...},{
   ...},{
   ...}]
let newArr = arr1.filter((item, index) => {
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值