一、如何用js判断null值
以下是不正确的方法:
var exp=null;
if(exp==null){
alert('is null')
}
exp为undefined时,也会得到与null相同的结果,虽然nullhe undefined不一样。
注意:要同时判断null和undefined时课使用如上方法
let exp=null;
if(!exp){
alert("is null")
}
如果exp为undefined,或者数字0,或false,也会得到与null相同的结果,虽然null和二者不一样。
注意:要同时判断null、undefined、数字零、false时课使用如上方法。
let exp=null;
if(typeof exp=='null'){
}
为了向下兼容,exp 为 null 时,typeof null 总返回 object,所以不能这样判断。
let exp=null;
if(!exp && typeof exp!="undefined" && exp!=0){
}
typeof exp!=“undefined” 排除了 undefined
exp!=0 排除了数字零和 false。
一、JavaScript数组
1. 遍历类(只有直接对item操作才会改变,返回值需要特别注意)
forEach map filter find some every for遍历
arr.forEach()
arr.forEach((val,index,arr)=>{
console.log(val,index,arr)
})
arr.map() //非常有用,做数据交互“映射”
//正常情况下,需要配合return,返回是一个新的数组
//若没有return,相当于forEach
注意:使用map,一定要return
arr.filter()过滤,过滤一些不合格“元素”,如果回调函数返回true,就留下
var ages=[1,2,3,4,5]
function checkoutAdult(age){
return age>=2;
}
let newArr = ages.filter(checkoutAdult)
console.log(newArr) //[2,3,4,5]
2. 增加删除类(改变原数组,返回值需要特别注意)
push && pop
push是从后面加一项,返回值是增加后的数组长度
pop是从后面删除一项,返回值是删除的那一项
shift && unshift
shift是从前面删除一项,返回值的删除的那一项
unshift从前面加入一项,返回值是增加后的数组长度
splice a.splice(n,m,l,...)
从第n项(包括n)删除m项,把l,…插入到n前面,返回值是删除的数组,原有数组改变。没 有第三项的时候表示只删除。没有2,3项的时候表示从第n项删除到最后。
3. 截取和拼接(原有数组不变)
** slice slice(n.m)**
从第n项(包括n)开始截取到m项(不包括m),没有第二项表示到末尾。**返回一个截取的 新数组,**不改变原数组,支持负数索引。
concat a.concat(b,c)
传参是想要拼接的数组/值,可以是多项传参,返回值是拼接后的新数组
4. 顺序相关(改变原数组,返回值为预期结果)
** reverse**
a.reverse()倒过来,改变原数组,返回来值为预想结果
sort
项目中sort都要有传参,改变原数组,返回来值是排序后的数组
5. 数组去重
二、js语法区别
export和export default的区别:
export导出**需要使用{}将对应的模块导出,同时在使用是import导入时需要使用{}**来引入相应的模块
export default导出时,不用使用{}进行导出对应的模块、函数、文件等。但是只能导出一个。同时import导入时也不用{}实现导入。
module.exports和exports都是node端在用,两者指向同一内存块,
module有一个exports,用于给module.exports添加属性。*****同时import导入时需要用{}实现导入。
二、处理数据
/** * 将价格转为分展示 * @method handlePrice * @params {number} price: 价格 * @return {string} 处理后的价格 */ function handlePrice(price) { if (typeof price === 'number') { let priceStr = price.toString(); let integerNum = 0; // 当前整数 let decimalsNum = 0; // 小数 let currentPrice = ''; // 处理后的数量 integerNum = priceStr.slice(0, priceStr.length - 2); integerNum = integerNum.length < 1 ? `0` : integerNum; decimalsNum = priceStr.slice(priceStr.length - 2, priceStr.length); decimalsNum = decimalsNum.length === 2 ? decimalsNum : `0${decimalsNum}`; currentPrice = Number(`${integerNum}.${decimalsNum}`).toFixed(2); return currentPrice; } else { throw new Error('处理价格传递的不是数值类型') }}
// 时间戳处理成2019.12.23
function dateTime(date){
var dateTime=new Date(parseInt(date))
var year=dateTime.getFullYear();
var month=dateTime.getMonth()+1;
var day=dateTime.getDate();
if(month<=9){
month='0'+month
}
if(day<=9){
day='0'+day
}
var timeDay=year+'.'+month+'.'+day; return timeDay;
}
//时间戳转换成日期时间1995.07.06 12:30:50
function js_date_time(unixtime) {
var dateTime = new Date(parseInt(unixtime))
var year = dateTime.getFullYear();
var month = dateTime.getMonth() + 1;
var day = dateTime.getDate();
var hour = dateTime.getHours();
var minute = dateTime.getMinutes();
var second = dateTime.getSeconds();
var now = new Date();
var now_new = Date.parse(now.toDateString()); //typescript转换写法
var milliseconds = now_new - dateTime;
if(month<=9){
month='0'+month
}
if (day <= 9) {
day = '0' + day
};
if (hour <= 9) {
hour = '0' + hour
};
if (minute <= 9) {
minute = '0' + minute
};
if(second<=9){
second='0'+second
}
var timeSpanStr = year + '.' + month + '.' + day + ' ' + hour + ':' + minute + ':' + second; return timeSpanStr;}
// 处理手机号码为156****6776
function jsonTel(number){
let tel = number.replace(number.substring(3, 7), "****")
return tel;
}
// 处理券码为1234-5678-9012
function couponCode(code){
let couponCode = code.substring(0, 4) + '-' + code.substring(4, 8) + '-' + code.substring(8, 12); return couponCode;}
// 把时间2019-12-23处理成2019年12月23日
function ymd(date){
let newTime=date.split('-');
let year = newTime[0] + '年' + newTime[1] + '月' + newTime[2] + '日'
return year;
}
// 获取当月时间的第一天和第二天
function getFullDate(targetDate) {
var D, y, m, d;
if (targetDate) {
D = new Date(targetDate);
y = D.getFullYear();
m = D.getMonth() + 1;
d = D.getDate();
} else {
y = fullYear;
m = month;
d = date;
}
m = m > 9 ? m : '0' + m;
d = d > 9 ? d : '0' + d;
return y + '-' + m + '-' + d;
};
//在其他页面页面运用
// 获取当月的第一天和最后一天
var nowDate = new Date();
var cloneNowDate = new Date();
var fullYear = nowDate.getFullYear();
var month = nowDate.getMonth() + 1; // getMonth 方法返回 0-11,代表1-12月
var endOfMonth = new Date(fullYear, month, 0).getDate(); // 获取本月最后一天
var endDate = utils.getFullDate(cloneNowDate.setDate(endOfMonth));//当月最后一天
var starDate = utils.getFullDate(cloneNowDate.setDate(1));//当月第一天
//40分50秒
function remainTime(time) {
var minute = Math.floor(time / (60 * 1000));
var second = Math.floor((time % (60 * 1000)) / 1000)
return minute + '分' + second + '秒'
}
//支付功能
function requestPayment(typeId, contentId, contentShardId, anonymous, subTypeId, callback) {
dataApi.pay.getUniteOrder({
typeId: typeId,
contentId: contentId,
subTypeId: subTypeId,
contentShardId: contentShardId,
openId: wx.getStorageSync('openId'),
anonymous: anonymous,
app: getApp().globalData.app
}).then(function (res) {
if (res.result.error) {
wx.showModal({
title: '提示',
content: res.result.error,
confirmText: '我知道了',
confirmColor: '#ff8022',
showCancel: false
})
} else {
wx.showLoading({
title: '支付中...',
mask:true
})
wx.requestPayment({
'timeStamp': res.result.timeStamp,
'nonceStr': res.result.nonceStr,
'package': res.result.package,
'signType': res.result.signType,
'paySign': res.result.paySign,
'success': function (res) {
wx.hideLoading();
callback()
},
'fail': function (res) {
wx.hideLoading();
wx.showToast({
title: '支付失败',
icon: 'none',
mask: true,
duration: 2000
})
}
})
}
}, function (msg) {
console.log(msg)
})
}
//判断是否是电话号码
function isPhone(tel){
var regx=/^1[34578]\d{9}$/;
return regx.test(tel)
}
console.log(isPhone(1562736776))//返回true和false
//验证是否是邮箱
function isEmail(email) {
var regx = /^([a-zA-Z0-9_\-])+@([a-zA-Z0-9_\-])+(\.[a-zA-Z0-9_\-])+$/;
return regx.test(email);
}
//验证是否是身份证
function isCardNo(number) {
var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return regx.test(number);
}
//去空格
trim:function(value){
return value.replace(/(^\s*)|(\s*$)/g,"")
}
//格式化手机号码
formatNumber:function(num){
return
}
//所谓的数字千分位形式是从个位数起,每三位之间加一个逗号,例如:1450068经过处理之后1,450,068
方法一:利用字符串提供的toLocaleString()方法处理,此方法最简单
const num=1450068;
console.log(num.toLocaleString())//1,450,068
方法二:
function toThousand(num){
var result=[];
var counter=0;
num=(num||0).toString().split('');
for(var i=num.length-1;i>=0;i--){
counter++;
result.unshift(num[i]);
if(!(counter%3)&&i!=0){
result.unshift(',')
}
}
return result.join('')
}
console.log(toThousand(111222333444))//111,222,333,444
//把数字大于10000的显示成1万(把5位数显示成万),把类似小于1000的显示成原来的1000(把四位数显示成4位)
function handlethousand(number) {
var number2 = parseFloat(number)
var number1 = number2.toString();
if (number1.length > 4) {
return number1 / 10000 + '万'
} else{
return number1
}}
let list = this.data.list;
//使用map方法要return val要不然就不显示
// let list2 = list.map((val, index) => {
// console.log(handlethousand(val.num))
// val.num = handlethousand(val.num)
// return val
// })
//使用forEach的话不能let list2=,要不然就没用
list.forEach((val,index)=>{
val.num = handlethousand(val.num)
})
this.setData({
list: list
})
// 处理时间戳js转化为几天前,几小时前,几分钟前,几年前
const getDateDiff=dateTimeStamp=>{
var minute=1000*60;//一分钟等于60秒
var hour=minute*60;//1小时等于60分钟
var day=hour*24;//1天等于24小时
var halfmonth=day*15;
var month=day*30;//一个月有30天
var year=day*365;//一年有365天
var now=new Date().getTime();//通过原型方法直接活佛当前时间的毫秒值,准确
var diffValue=now-dateTimeStamp;
var result;//返回来的
if(diffValue<0){
return;
}
var yearC=diffValue/year;
var month=diffValue/month;
var weekC=diffValue/(7*day);
var dayC=diffValue/day;
var hourC=diffValue/hour;
var minC=diffValue/minute;
if(yearC>=1){
result=''+parseInt(yearC)+'年前';
}
if(monthC>=1){
result=""+parseInt(monthC)+'月前';
}else if(weekC>=1){
result=""+parseInt(weekC)+'周前';
}else if(dayC>=1){
result=""+parseInt(dayC)+'天前';
}else if(hourC>=1){
result=""+parseInt(hourC)+'小时前';
}else if(minC>=1){
result=""+parseInt(minC)+'分钟前';
}else{
result="刚刚";
}
return result;
}
//数组中每5条数据添加一条数据,分页功能每页显示10条才行
let arr1 = [{
name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 }, { name: 'yier', age: 18 },
]
console.log(arr1.length)
var arr2 = arr1.slice(0, 5)
console.log(arr2)
let newAd = [{
name: '黄意芳',
age: '18'
}]
let arr4 = arr1.slice(5);
let newList = arr2.concat(newAd).concat(arr4).concat(newAd)
console.log(newList)
//把分转化成
//String.replace(/\s/g,'')中的/\s/g表示什么意思
'/\s/g'中的/xxx/表示正则表达式,'\s'表示正则匹配字符串中的空字符,'g'表示全部匹配
三、ES6语法
1. ES6简介
全称ECMAScript6.0,是JavaScript的下一个版本标准,2015.06发版
JavaScript语言的国际化标准
2. let和const
let 声明的变量只在let命令所在的代码块内有效。
1、let 和var关键字的用法基本一样
let food='西兰花的用法基本一致'
food='西兰花炒花菜'
console.log(food)
2、let没有变量提升,变量的声明:会提升到当前作用域的顶端
const声明一个只读的常量,一旦声明,常量的值就不能改变
3. 解构赋值
注意:对于做交互特别有用,ajax
let [a,b,c]=[1,2,3]
注意:左右两边,结构格式要保持一致
let json = {
name: '意儿',
age: 18,
color: "white"
}
let { name, age, color } = json;
let { name: n, age: a, color: c } = json //改为另外的名字
解构时候可以给默认值
let [a,b,b="默认值"]=['aaa','bbb']
4. 字符串模板以及字符串新增
(1) 字符串模板:
优点:可以随意换行
`${变量名称}`
(2)关于字符串一些东西
字符串查找:
str.indexOf(要找的东西) 返回索引(位置),没找到返回-1
str.includes(要找的东西) 返回值true/false
(3)字符串是否以谁开头
str.startWith(检测东西)
(4)字符串是否以谁结尾
str.endsWith(检测东西)
重复字符串:
str.repeat(次数)
填充字符串:
str.padStart(整个字符串长度,填充东西) 往前填充
str.padStart(整个字符串长度,填充东西) 往后填充
let str="意儿";
let padStr="亲爱的";
str.padStart(str.length+padStr.length,padStr) ==亲爱的意儿
5、函数默认参数、箭头函数、剩余参数
1、函数默认参数
function show(x=0,y=0){
console.log(x,y)
}
show()
2、函数参数默认已经定义了,不能再使用let,const声名
function show(a=1){
let a=10;//不能此处是错误
console.log(a)
}
show()
扩展运算符、Rest运算符
[1,2,3,4] ...[1,2,3,4] ===1,2,3,4
1,2,3,4 ...1,2,3,4 ===[1,2,3,4]
箭头函数
()=>{
语句
return
}
注意:
1、this问题,定义函数所在的对象,不在是在运行的对象时所在的对象
2、箭头函数里面没有arguments,用‘...’
3、箭头函数不能当构造函数
function省略掉,替换为=>
参数只有一个时,可以省略()
函数体只有一行时,可以省略{}
函数体只有一行时,并且有返回值时,如果省略了{},必须盛磊return
//无参数,一行,无返回值的 函数
let func1=function(){
console.log('hello ITheima')
}
let func1=()=>console.log('hello ITheima')
//1个参数,一行,无返回值函数
let func2=function(p1){
console.log(p1)
}
let func2=p1=>console.log(p1)
//2个参数,多行,无返回值的函数
let func3=function(p1,p2){
console.log(p1)
console.log(p2)
}
let func3=(p1,p2)=>{
console.log(p1)
console.log(p2)
}
//无参数,一行,有返回值的函数
let func4=function(){
return 'ITheima'
}
let func4=()=>'ITheima'
let func4Res=func4()
//1个参数,一行,有返回值的函数
let func5=function(p1){
return p1+'IThemia'
}
简写:
let func5=p1=>p1+'IThemia'
let res=func5('深圳')
//2个参数,多行,有返回值的函数
let func6=function(p1,p2){
console.log(p1,p2)
return p1 + p2 + 'ITheima'
}
简写:
let func6=(p1,p2)=>{
console.log(p1,p2);
return p1+p2+'ITheima'
}
func6('深圳','黑马')
5、async函数(关于async里面try/catch的一个问题)
ES2017标准引入了async函数,使得异步操作变得更加方便
它是Generator函数的语法糖
1、try....catch是同步代码
2、异步,已经脱离了当前的主线程,可以想象成一个新的定时任务里去执行;只是能与主线程共享内存,堆栈等
async函数有多种使用形式
//函数声明
async function foo(){}
//函数表达式
const foo=async function(){}
//对象的方法
let obj={
async foo(){}
}
obj.foo().then(){}
//Class的方法
class Storage{
construtor(){
this.cachePromise=caches.open("avatars")
}
async getAvatar(name){
const cache=await this.cachePromise;
return cache.match(`/avatars/${name}.jpg`)
}
}
const storage=new Storage();
storage.getAvatar('jake').then(())
//箭头函数
const foo=async ()=>{};
3、返回Promise对象
async函数返回一个Promise对象。
async函数内部return语句返回的值,会成为then方法回调函数的参数
async function f(){
return 'hello world'
}
f().then((v)=>{
console.log(v)
})
6、this指向及改变this指向的方法
一、函数的调用方式决定了this的指向不同
1.普通函数调用,此时this指向window
function fn(){
console.log(this);//window
}
fn();//window.fn(),此处默认省略widow
2.构造函数调用,此时this指向实例对象
function Person(age,name){
this.age=age;
this.name=name;
console.log(this) //此次this分别指向Person的实例对象p1,p2
}
var p1=new Person(18,'zs')
var p2=new Person(18,'ww')
3、对象方法调用,此时this指向该方法所属的对象
var obj={
fn:function(){
console.log(this);//obj
}
}
obj.fn()
4、通过事件绑定的方法,此时this指向绑定事件的对象
<body>
<button id="btn"></button>
<script>
var oBtn=document.getElementById("btn");
oBtn.onclick=function(){
console.log(this);//btn
}
</script>
</body>
5、定时器函数,此时this指向window
setInterval(function(){
console.log(this);//window
},1000)
二、更改this指向的三个方法
1、call()方法
var Person={
name:'lixue',
age:21
}
function fn(x,y){
console.log(x+","+y)
console.log(this)//这里指向的是window
}
fn('hh',20)
没错,就像上面说的,普通函数的this指向window,现在让我们更改this指向
var Person={
name:"lixue",
age:21
}
function fn(x,y){
console.log(x +","+y)
console.log(this)
console.log(this.name)
console.log(this.age)
}
fn.call(Person,'哈哈',20) //这样就指向Person
2、apply()方法
apply()与call非常相似,不同之处在于提供参数的方式,apply()使用参数数组,而不是参数列表
3、bind()方法
bind()创建的是一个新的函数(称为绑定函数),与被调用函数有相同的函数体,当目标函数被调用时this的值绑定到bind()的第一个参数上。
三、改变this指向的例子
var oDiv1=document.getElementById("div1");
oDiv1.onclick=function(){
setTimeout(function(){
console.log(this)//这里是window
},1000)
}
定时器里的this指向window,那么如何改成指向div呢
oDiv1.onclick=function(){
setTimeout(function(){
console.log(this)//这里是对象div
})
}
因为在定时器外,在绑定事件中的this肯定指向绑定事件的对象div,用call和apply都行,
上图就是用bind改变了this指向
四、JavaScript的基础学习
1、JavaScript数据类型
值类型(基本类型):
字符串(String) 数字(Number) 布尔(Boolean) 对空(Null) 未定义(Undefined) Symbol
引用数据类型:
对象(Object) 数组(Array) 函数(Function)
2、对象(包括属性和方法)
var person={
firstName:'John',
lastName:'Doe',
age:50
}
访问对象属性(两种方法)
person.lastName
person["lastName"]
3、encodeURL和encodeURLComponent的作用及应用
将文本字符串编码为一个有效的统一资源标识符(URL)
最多使用的应为encodeURLComponent,它是将中文、韩文等特殊字符转换成utf-8格式的URL编码,所以如果给后端传递参数需要使用encodeURLComponent时需要后台解码对utf-8支持。
4、replace
replace(/\/g,'') 作用是把/替换成''
例如:
var aa="adsdd/ssss/"
var bb=aa.replace(/\//g,"") adsddssss
js正则去除html代码里img标签里的style
replace(/<img/g, "<img style=\"display:none;\"")
5.module.exports
//导出
module.exports={
title:'yier'
}
//引入
const defaultSetting=require('文件的路径')
//使用
defaultSetting.title
6、es6:export default和export区别
1、export与export default均可用于导出常量、函数、文件、模块等
2、你可以在其他文件或模块中通过import+(常量|函数|文件|模块)名的方式,将其导入,
以便能够对其进行使用
3、在一个文件或模块中,export、import可以有多个,export default仅有一个
4、通过export方式导出,在导入时要加{} ,export default则不需要
1.export
//a.js
export const str = "blablabla~";
export function log(sth) {
return sth;
}
对应的导入方式:
//b.js
import { str, log } from 'a'; //也可以分开写两次,导入的时候带花括号
2.export default
//a.js
const str = "blablabla~";
export default str;
对应的导入方式:
//b.js
import str from 'a'; //导入的时候没有花括号
使用export default命令,为模块指定默认输出,这样就不需要知道所要加载模块的变量名
//a.js
let sex = "boy";
export default sex(sex不能加大括号)
//原本直接export sex外部是无法识别的,加上default就可以了.但是一个文件内最多只能有一个export default。
其实此处相当于为sex变量值"boy"起了一个系统默认的变量名default,自然default只能有一个值,所以一个文件内不能有多
个export default。
// b.js
本质上,a.js文件的export default输出一个叫做default的变量,然后系统允许你为它取任意名字。所以可以为import的模块起任何变量名,且不需要用大括号包含
import any from "./a.js"
import any12 from "./a.js"
console.log(any,any12) // boy,boy
//导出
module.exports={
title:'题目',
showSetting:false
}
//导入
import defaultSettings from '@/setting'
const {title,showSetting} = defaultSettings