js 基础运用、技巧、新特性

151 阅读6分钟

使用至少五种不同方式选中页面元素

  document.getElementById("one");
  document.getElementsByClassName("two")[0]; //集合
  document.getElementsByTagName("div")[0]; //集合
  document.querySelector(".two");//只能选中一个;有多个类名或标签名 获取第一个 dom
  document.getElementsByName('divs') //集合
  document.querySelectorAll('div') //集合
  document.querySelector("#one");
  document.querySelector("input[value=按钮3]")//("input:nth-child(2)")或("input[type=button]")

静态 Nodelist 和 动态 Nodelist

let a =  document.querySelectorAll('div') //集合 静态 Nodelist
  console.log(a);//4
  a.forEach(()=>{
     document.body.appendChild(document.createElement('div'))
  })
console.log(document.querySelectorAll('div'));//8

 let c = document.getElementsByTagName('div')//动态 Nodelist
  console.log(c);//4
  for (let i = 0; i <= c.length; i++) {
  //会死循环
    // document.body.appendChild(document.createElement('div'))
  }
console.log(document.getElementsByTagName('div'));//死循环了

使用dom规则提供API,在JavaScript脚本中修改节点样式

  document.getElementById("one").style = "color:red";
  var to = document.getElementsByClassName("two")[0];
  to.style.cssText = "color:red; font-size:20px;";
  document.querySelector("p").classList.add("p1");
  .p1 {
    color: rebeccapurple;
  }

使用dom规则提供API,在JavaScript脚本中创建节点,并将节点添加至页面中

 let div = document.createElement("div")
 //innerHTML 是获取该元素所有节点(文本、标签)
 div.innerHTML =`
  <p>innerhtml</p>
 `
document.getElementById('create').appendChild(div)//图2.1效果
document.getElementById('create').append(div)//和图2.1效果一致,
document.getElementById('create').append('<p>innerhtml</p>')//append 可以追加文本
document.getElementById('create').appendChild('<p>innerhtml</p>')//appendChild 不支持追加文本

图2.1 image.png

appendChild 与 append 的区别

  1. 都接受标签节点( Node ), appendChild 不能追加文本节点, append 可以追加文本节点
  2. appendChild 返回值, append 没有返回值
let r = document.getElementById('create').appendChild(div)
console.log(r);//<div> </div>
let r = document.getElementById('create').append(div)
console.log(r);//undefined
  1. appdenChild 仅允许添加一个项目,append 允许添加多个项目
 div.innerHTML =`
  <p>innerhtml</p>
 `
document.getElementById('create').append(div,'moretext')//都生效
document.getElementById('create').appendChild(div,'moretext')//第一个生效

this 用法

  1. this用法1:普通函数this指向window
  var first = "first";
  function this1() {
     console.log(this.first);
  }
  window.this1();//相当于是 window 在调用它
  1. this用法2:对象指向
function sec() {
     console.log("sec:", this.name);
   }
   var second = {};
   second.showname = sec;
   second.name = 'sy'
   second.showname();//'sec',sy
  1. this用法3:构造函数,this指向实例化的对象
   function third() {
       this.name = "third in function";
       this.show = function () {
          console.log(this.name,'用法3');
       }
     }
     var thirdObj = new third();
     thirdObj.name = "Third";
     thirdObj.show();//Third
  1. this用法4:a.apply(obj),把a的this指向obj
 var four = {
    name: "four",
    show: function () {
        console.log("arg1",arguments[0]);//aaaa
        console.log("arg2",arguments[1]);//bbbb
        console.log(this.name);//app name
    },
    showCall: function (opt) {
        console.log(opt.a);//10
        console.log(opt.b);//11
        console.log(this.name);//app name
        console.log("arg",arguments[0]);//{"a":10,"b":11}
        console.log("arg2",arguments[1]);//3
    }
}
 var app = { name: "app name" };

   four.show.apply(app, ["aaaa", "bbbb"]); //只能传一个参数:数组

   four.showCall.call(app, { "a": 10, "b": 11 },3,4,5);

小案例

 console.log("0.1+0.2=", 0.1+0.2); //为什么不等于0.3,计算机精度问题
 var undef; //定义了变量却没赋值,系统默认值为undefined
 
 //对象取值
 var obj = { "name": "严礼笑", "age": 18, "major": "WEB前端" };
 let key = 'age'
 conole.log(obj[key],'方式一',obg.age,'方式二')
 
 //去掉空格
 let int1 = '2 3 4 '
 int1.replace(/\s+/g, ""); //234 去掉所有空格
 
 //根据值获取对应的文字提示
 //方法一
let actions = new Map([[1,'成功'],[2,'失败'],[3,'进行中'],[4,'未开始']])
console.log(actions.get(1));//成功
//方法二
let sort = { type_1: "产品信息", type_2: "支付", type_3: "填写信息", type_4: "健康告知", type_5: 4 }
let msg = sort[ele.name]//产品信息

//判断是否为工作日
const isWeekday = (date) => date.getDay() % 6 !== 0; 
console.log(isWeekday(new Date(20211111)));

//滚动到页面顶部
const goToTop = () => window.scrollTo(00); 
goToTop();

//网站变黑白
filter: grayscale(1);

敏感词替换

  1. 方法1,截取再拼接
let str6 = "我们的产品全国第一";
let startstr = str6.substring(0, 7);
let newsstr = startstr + "**";//我们的产品全国**
  1. 方法2,匹配(全局)替换
let str = "我们的产品全国第一,第一"
console.log(str.replace(/第一/,"**"))//我们的产品全国**,第一
console.log(str.replace(/第一/g,"**"))//我们的产品全国**,**
  1. 方法3,匹配(全局)替换
 let badwords = new RegExp("第一","g");
 let str = "我们的产品全国第一,第一";
 let goodwords = str.replace(badwords,"**");//我们的产品全国**,**
 
 let reg = new RegExp("第一");
 let new = str.replace(reg,"**");//我们的产品全国**,第一

some 和 every 返回的是 Boolen 类型

  1. some 数组中有一个元素满足条件 都 返回 true
var age = [18,19,20,21,22,80];
let g = age.some((ele,index,array)=>{
    return ele>50
})
console.log(g);//true
  1. every 数组中所有元素满足条件 才 返回 true
var age = [18,19,20,21,22,80];
let f = age.every((ele,index,array)=>{
    return ele >= 18
})
console.log(f);//true

map 和 filter 返回的是数组

var age = [18,19,20,21,22,80];
let h = age.map(e=>{
    if(e>18){
        return e
    }
})
console.log(h);//[undefind,19,20,21,22,80]
var age = [9,16,25,36,49,64];
console.log(age.map(Math.sqrt),'g');//[3,4,5,6,7,8]

let j = age.filter(e=>{
    return e >18
})
console.log(j);//[19,20,21,22,80]

for in for of forEach 的区别

1. for in:循环数组、字符串取其下标
2. for of:循环数组取每个值、对象取键名
3. forEacch:只能循环数组,可以取下标和每个值

js 判读是否在抖音app端

function isDouyinClient(){
 var ua = window.navigator.userAgent.toLowerCase();
  if(ua.match(/aweme/i) == 'aweme'){ 
    return true;
  }else{
    return false; 
  } 
}

周岁判断

 let idcar = "510502200008013566"
   let nowdate = new Date()
   let month = nowdate.getMonth() + 1//当前月份
   let date = nowdate.getDate()//当前日
   let year = nowdate.getFullYear() - idcar.substring(6, 10) - 1 //2022 - 1999
   if (idcar.substring(10, 12) < month || (idcar.substring(10, 12) == month && idcar.substring(12, 14) <= date)) {
      console.log(idcar.substring(12, 14));
      year++
   }
   console.log(year);

数据处理

let res = [{name:'ll',sex:1,age:12,img:'/img/photo.png'},{name:'lin',sex:2,age:18,img:'/img/photo.png'},{name:'ying',sex:0,age:20,img:'/img/photo.png'}]
let r = res.map(i=>{
    return {
        title:i.name,
        sex:i.sex === 1?'男':i.sex === 0?'女':'保密',
        avatar:i.img
    }
})
//r 的值[{title: 'll', sex: '男', age: 12, avatar: '/img/photo.png'},{title: 'lin', sex: '保密', age: 18, avatar: '/img/photo.png'},{title: 'ying', sex: '女', age: 20, avatar: '/img/photo.png'}]

reduce 求和

let nums = [2,3,4,2]
let sum = nums.reduce(function(total,curr,index){
    // console.log(index,'当前元素的索引');
    // console.log(total,'初始值');
    // console.log(curr,'当前元素');
    return total + curr
})
console.log(sum,'总和');

过滤所有虚值

let filter = ["shi", false, 0, 5, null, 1, undefined, "ying"];
console.log(filter.filter(Boolean)); //['shi', 5, 1, 'ying']

响应式

function init() {
    const width = document.documentElement.clientWidth
    document.documentElement.style.fontSize = width / 10 + 'px'
}
// 首次加载
init()
// 监听手机旋转
window.addEventListener('orientationChange', init)
// 监听手机窗口变化
window.addEventListener('resize', init)

ES新特性

function(a,b){
 b?.();//条件式访问属性ES2020新增
}
let a = 2
let b = 3
[a,b] = [b,a]//ES解构赋值,不用第三个变量也能互传值

//find 查找
let arr = [{v: 1}, {v: 2}, {v: 3}, {v: 4}]
//从头开始遍历,找到就结束
let fin = arr.find(ele => ele.v > 2)//{v: 3} 查找匹配的元素
let finx = arr.findIndex(ele => { return ele.v > 2 })//2 匹配元素的下标
//从末尾开始遍历,找到就结束
let finl = arr.findLast(ele => ele.v > 2)//{v: 4}
let finxl = arr.findLastIndex(ele => ele.v > 1)//3

[...'123']

模块导入导出

commonjs 导入导出(只能在node里使用,无法在html文件中使用)

导出:
function common() {
    console.log("cool");
}
// 将导出的参数以对象的方式导出
module.exports = {
    common: common,
    data: 'demo'
}
// 导出单个参数
module.exports = common;
导入:
let demo = require("./demo");

ES6 导入导出(需将引入html的文件类型设置为type="module",使用node运行无法识别此方式)

导出:
export default data;//一个文件里只能使用一次
export { data, data1 };//多个导出
export function demo(){
    console.log("demo");
}//可以多次使用此方式
导入:
import {a as d,demo} from './ESmode.js';//as别名,在导出端也可用
import c from './ESmode.js';

arguments

是所有(非箭头)函数中都可以用的局部变量;当传递的参数不知道个数时,就可以 使用 arguments 获取参数值

//N个数求和
function sumn(){
     var su = 0;
     for(var i=0; i<arguments.length; i++){
         su += arguments[i];
     }
     return su;
}

时间转换、幂运算、操作符

//获取当前时间的时间戳
+new Date() 
+new Date('2023-004-21 14:41:00')//指定时间戳

//幂运算
2 ** 3 //8
2 ** 2 ** 3 == 2 ** (2 ** 3) //256

//逗号运算
let y = (x => (x++ , x))
console.log(y(0));//1 ,返回的最后一个x

//取值判断
null?.name //undefined
let arr = []
arr?.[0] //undefined

//|| 和 ??
x = x || '未知' //`||`会在左侧操作数为`Falsy`时返回右侧操作数:`false`、`0`、`-0`、`0n`、`""`、`null`、`undefined` 和 `NaN` 为 `Falsy`
x = x ?? '未知' //空值合并运算符`??`当且仅当左侧操作数为`null`或者`undefined`时才会返回右侧操作数。

//二进制运算符
与 & 运算:111,其余为01 & 1 => 1, 0 & 11 & 00 & 0 => 0)
或 | 运算:000,其余为10 | 0 =>0, 0 | 11 | 01 | 1 => 1)
异或 ^ 运算:相同为0,不同为10 ^ 01 ^ 1 > 0, 0 ^ 11 ^ 0 => 1)
非 ~ 运算:转换为32位二进制,每位取反(任何非负数非运算结果都是 -(x + 1),反之 (x - 1)) 

//无需中间变量直接交换两变量的值
a = a ^ b
b = a ^ b
b = a ^ b