执行js
//1.语法分析,
//2.预编译,{
1.创建全局go对象(全局预编译)
{01. 先找变量声明并作为GO对象属性,值为undefined,下面一样;
02.再找函数声明;
}
2.局部ao对象;(局部预编译){
01.现在局部变量声明,包括形参并作为AO对象属性,值为undefined,下面一样;
02.再把形参与实现赋值;
03.最后在找函数声明;
}
}
//3.执行代码(变量赋值等)
js组成
ECMAScript(ES语法部分)es5,es6;
DOM:document object model(文档对象模型) 提供一些访问操作网页 内容的手段;
BOM: browse object model(浏览器对象模型)
注意
js严格区分大小写
浏览器如何执行html文件
1.解析html,下载js,cs文件创建dom树
2.解析css,创建css规则树(cssom)
3.将dom树和css规则树结合 创建渲染树(render tree)
4.布局和绘制
编写高性能的javascript
a) 遵循严格模式:"use strict";
b) 将JS脚本放在页面底部,加快渲染页面;
c) 将JS脚本将脚本成组打包,减少请求;
d) 尽量使用局部变量来保存全局变量;
e) 尽量减少使用闭包;
f) 使用window对象属性方法时,省略window;
g) 尽量减少对象成员嵌套;
h) 缓存DOM节点的访问;
i) 通过避免使用 eval() 和 Function() 构造器;
j) 给 setTimeout() 和 setInterval() 传递函数而不是字符串作为参数;
k) 尽量使用直接量创建对象和数组;
l) 最小化重绘(repaint)和回流(reflow)。
重绘和回流
重绘:当前页面的一些元素的外观(颜色)发生改变的时候,就会产生重绘;
回流:当页面中的一些元素的布局(宽高)发生改变的时候,就会发生回流;
执行js
外部引入;
内部(内嵌);
行内;
语言区别
编译型语言:c c++ java有个编译过程 编译完执行效率会很高;
解释性语言:js python 边解释边执行
打印语句
1.console.log( 变量,变量 ) ;
2.console.log( typeof (变量名)) ;
声明变量
变量名 由英文 数字 下划线 $符号组成,不能用数字开头,
关键字等定义 变量名,区分大小写,不能重复声明,先声明后使用
var 变量名 = 值;(es5语法)
let 变量名 = 值;(es6语法)
查看数据类型
typeof(数据或变量名)
数据类型
基本数据类型
存在栈里面比较的是实际值,不比较类型(==)
null==underfined
5==‘5’
不比较类型;
(===)类型,值都比;
-
number(12; 12.5)
-
字符串 es5(单双引号都行) es6(反引号 tab键``)
拼接用加号 var i = 变量+变量(es5)
${} (es6拼接)可用运算符;
let i =
你好,${再见}
;3.布尔类型
4.未定义(undefined)
5.null–空对象
6.bigint 超大大数
7.symble
引用数据类型
放在堆里面;变量名放在栈里面;比较的变量名指向的地址–重要。
两个数组指向同一地址时改一全改;数组对象一致;
//定义数组
let arr1 = arr2 = [1,2];
arr1 = arr2;//true
arr[1] = 3;
arr[1] = arr2[1] = 3;
let arr1 = [];
let arr2 = [];
arr1 ==arr2;//fales
instanceof
//判断是否都构造函数构造出来的
new String('12') instanceof String;//true
1.数组
//定义数组
let arr = [1,2];
var arr = new Array(10);//创建长度为10的空数组;
var arr = naw Array(10,20,30,40)//创建[10,20,30,40]数组;
//数组长度设置数组长度;
let arr = [1,2];
arr.length() = 0;
//修改:重新赋值;
arr[0] = 3;
var i = [1,2,3,4]
i.splice(0,1,2);
//添加
arr.push(值);//从数组最后添加
arr[arr.length] = 值;
arr.unshift(值);//从数组前面添加
//删除
arr.pop();//从最后一个数开始删除
arr.shift(值);//从前面开始删除
//查找
arr.indexOf(查找的值);//没有返回-1;
arr.includs()布尔值
//数组的拼接 会把链接的数组放在一个新数组里面;
arr.concat(arr1,arr2);
// 条件判断
arr.every(f(参数,index,array){
return 条件;
});//有个不满足,则返回false
arr.some(f(参数,index,array){
return 条件;
});//有个满足,则返回true
//遍历数组
arr2 = [];
//代替for循环
forEach(function(i,index,array){
//实现数组深拷贝 不能用 break return
arr2.push(i);
});
//转换字符串
1.arr.toString();
2.arr.join('链接值');
//map方法 遍历数组,返回新数组;
arr.map(function(i,index,array){
return i*2;//新数组是老数组的两倍;
})
//reduce方法 对数组进行累计计算 ,返回计算结果
arr.reduce(function(titla,currentValue,index,array){
//titla 累计计算的结果;
//currentValue 现在的数组值
return titla+currentValue;//实现数组累加;
},initial(初始值) 0)
slice(start,end) //会返回截取的数组段,!!!不会修改原数组;
splice(start,length,value)
// start :从哪里开始切割 length:切割的长度 设为零实现插值 value:从切割的地方插值!!!会修改原数组
//数组排序 arr.sort(function(a,b){});会修改原数组
arr.sort(function(a,b){
return a-b;//升序 b-a降序;
})
//filter 过滤器 把数组里面符合条件的返回新数组,!!不修改原数组
arr.filter(function(currentValue,index,array){
return 条件;
})
//se6!!!!!!!!!!!!
arr.keys().next();
for(let i of arr.keys()){};
for(let i of arr.values()){}
arr.entries();
for(let [x,y] of arr.entries()){
x 索引
y 值
}
//创建新数组
let x = Array.of(值);
Arrayis([]);//true;
//把类似数组的对象转换为数组;
let newarr = Array.from(obj);//可用于set类型的数据结构;
//数组的合并
let i =[...arr1,...arr2]
//数组的深拷贝
let [...newarr] = arr;
//解构数最大值
arr = [];
Math.max(...arr)
2.对象
let object = {
name:'noname',
age:20,
father:['我','你' ,'你好'],
属性名:值,
方法名:fuction(){
代码块
return ;
},
};定义对象
//调用,修改对象中数据方法
//对象.属性名字 =修改 ;
//对象['属性名'] = 修改;
//对象.方法 =修改 ;
//对象['方法名'] = '修改';
//对象.方法名();调用
//对象[变量名] = 修改;
添加对象属性
对象.属性名 = '';//当对象没有该属性时会自动添加
对象['属性名'] = ''
对象.方法名 = function(){};
对象['方法名'] = function(){};
//删除属性,方法
dalete obj.属性名(方法名);
//获取对象属性名
1.Object(内置构造函数).keys(obj(对象名))//返回数组
2.for(var x in obj){
x:属性名
obj[x]:属性值
}
//获取对象属性值,
1.obj.valueOf() //返回对象;
2.Object(内置构造函数).values(obj(对象名))//返回数组
//entries //返回键名 与键值;
let arr = {
name: 's',
age: 'z'
};
Object.entries(arr).forEach(([x, y]) => {
console.log(x, y)
})
//in操作符 判断对象是否有该属性或方法;
(keys in obj)有为true 否则false;
-------------------------
this关键字 ----指向调用时的对象地址;---重要
//对象的合并
let objAll = {...obj1,...obj2};
函数
定义
//1. let 函数名 = function(参数){
代码块
return ;函数返回值
代码 //return 后面不执行;
}
//2. function 函数名(参数){}
//3. 立即执行函数 避免变量重名问题;
(function(){
代码块,页面加载就执行;
开发员A
})();
(function(){
代码块,页面加载就执行;
开发员B
})();
(function(){
代码块,页面加载就执行;
开发员C
})();
//4.arguments 是每个函数对象的方法,用显示传入的参数,是数组的格式
//如
function mana(num1,num2){
console.log(mana.arguments);
}
mana(100,2);
this对象
this关键字 ----指向调用时的实例化对象地址;
如在顶层对象window下写
console.log(this)
等同于
window.conle.log(this)
实际上是window对象下的方法调用的this
所以这时候的this指代的是window对象;
即this 没有特定指向地址,谁调用,就指代谁
数据转换
任何类型可转换为字符串(.toString());
转化为number :
NaN(not a number) 类型是number 与任何值都不相等包括NaN;
1.parseInt()数字字符串转number 从第一个判断,如果是数字字符则继续转换,否则停止转换;
第一个如果不是数字字符则返回NaN 如:
console.log(parseInt('assa123'))
2. - * / %
转换为布尔值 :
Boolean() ;
基本数据类型
false: 0,'',null,undefined, NaN;其他基本true
应用数据类型权威true;
if语句
if(条件判断){代码块}
else if(){}
else{}
for语句
for(;条件判断;){
循环体
}
如
for(var i = 0;i<5;i++){循环体}
for(var i = 0,var j = 0;i<5,j<10;i++,j++){循环体}
//当判断条件为两个的时候 条件判断为最后一个条件;
变量提升
变量名在声明的时候会把变量声明提在当前作用域最前面(最上层),
但是不会把赋值也提升在前面;
函数提升
function 函数名(){}//整个函数会提升到当下作用域最上层;
let 变量名 = function(){}//只提升变量名;不提升函数;
作用域
全局作用域
在web浏览器中是window下的作用域,全局变量能作用在局部;
GO:全局对象
局部作用域
局部变量是函数作用域,只能作用在函数里面,形参也是函数里面的变量,如果在局部变量里面没有定义一个变量,那就会往父级查找该变量,
AO:局部对象
Math内置对象
1.Math.ceil(x) 向上取整
2.Math.floor (x)向下取整
3.Math.random()取随机[0,1)数 不用传参数
4.Math.round(x)四舍五入取整
//随机获取1-45之间的数
Maht.floor(Math.random()*45+1);
//45度余弦值
Math.cos(Math.PI/4);
number数据类型的操作
// 1. isNaN检测是否不是一个数值(是数值返回false 不是返回true)
isNaN('sacsc')//true
isNaN('100')//false 会将能转换成数值的转换为数值在进行判断
//转换为number类型
//2.parseInt();
Number();
//3.小数bug
0.3-0.2//0.999999
//避免
(0.3*10-0.2*10)/10;
//4.保留几位小数
var num =2.446242342;
num = num.toFixed(2);
字符串操作
var srt = 'hello woild'
//注意当引用字符串对象里面的属性或方法时,会自动调用 new 临时创建对象,并在引用结束销毁临时对象;
//1.字符串转对象
var objsrt = new String(str);
//2.获取字符串长度
str.length;
//3.获取指定位置字符
str.charAt(index)//返回输入index下的字符
//4.去掉字符串前后空格
str.trim();//返回新字符串,不修改字符串
//5.字符串的切割
str.split('l');//把字符按l切割并且删除l返回新的字符串数组,不修改原字符串;
//6.查找
str.indexOf(findvalue,start-index)
str.includes(findvalue)
//str.padStart(length,加入字符串) 返回新字符串 ,不修改原字符串;如果输入length小于依赖的字符串 则返回依赖的字符串
//padEnd(length,加入字符串) 在字符串后面添加
var str = 'casacs';
var i = str.padStart(str.length+5,'nihao');
//字符串大小写转换
str.toLowerCase()//小写
str.toUpperCase()//大写
// es6 扩展;
//srt.charCodeAt(index) 返回字符的code编码
//srt.repeat(2) //返回字符的两倍复制
//切割url
var url = 'https://mbd.baidu.com/? n_type=0&p_form=1'
var data = url.spli('?')[1].split('&')
//其他切割方式
// str.substring(start(包括),end(不包括))不支持负数;
//str.slice(start(包括),end(不包括))支持负数;
//str.substr(start,length);
//查看方式
str,indexOf('')有就返回下标,没有返回负一;
字符串replace()方法利用正则匹配
//str.replace('字符串或正则表达式','字符串或函数') 返回新字符串 不修改原字符串
var reg = /(邓)(鑫)/g;
str1="擦刹车市场邓鑫按时吃邓鑫";
var x = str1.replace('邓鑫','再见');
console.log(x) //只匹配第一个;
//=====================================================
// 匹配电话号码
var reg = /1[0-9](\d{9})/g;//!!!!!!!!!
str1="擦刹车市场 18162771236 按时吃三 19162771236";
console.log(str1.match(reg));
var x = str1.replace(reg,($,$1) => {
console.log($,$1);//每一次匹配成功都调用后面函数传入的参数是正则匹配出来的结果;//18162771236 $1 = 162771236,19162771236
return '你好'
});
console.log(x);// 擦刹车市场 你好 按时吃三 你好;
//===============================================================
//匹配中文
var reg = /(邓)(鑫)/g;
str1="擦刹车市场邓鑫按时吃王鑫";
console.log(str1.match(reg));
var x = str1.replace(reg,($,char1,char2) => {
console.log($);//每一次匹配都调用后面函数传入的参数是正则匹配出来的结果;
console.log(char1);//第二个是正则第一个括号的字符 :邓
console.log(char2);//第三个是正则第二个括号的字符 :鑫
return `<span>${$}</span>` //<span>邓鑫</span>
});
document.write(x) //识别span标签可通过css修改样式
字符串match方法
str.match(reg)//reg为正则表达式 返回匹配的值组成的数组
var reg = /(adc|bwe)/g;//匹配adc或bwe 只匹配|两边
console.log('adcedfbwe'.match(reg))
//返回["adc", "bwe"]
一元操作符
++:
前置时:先自加在运算
后置时:先运算在自加
--:同上;
逻辑运算符
//1.逻辑非 !;返回布尔值
//2.逻辑与 &&;优先级高于||(或);
语句1&&语句2
当语句1成立时,返回语句2
当语句1不成立时,返回语句1
常用与for循环中条件判断
for(条件一&&条件二){};
//3.逻辑或 ||;
语句1||语句2
当语句1成立时,返回语句1;
当语句1不成立时,返回语句2;
for(条件一||条件二){};
switch语句
switch(变量或值){
case 情况一:
语句;
break;
case 情况二:
语句;
break;
case 情况三:
语句;
break;
default
语句;
break;
}
for in语句
//遍历对象
for(var i in object(对象)){
//i是对象中的keys
//object[i];对象属性值
代码块;
}
for of语句
for of 语句能遍历很多 可迭代的
=====================================================
//循环数组 相比forEach ,for of可以在循环时使用break ,return等语句
1.for of 循环
var i = [1,2,3,4,5]
for(var x of i){
console.log(x)//输出1,2,3,4,5
}
2.for in循环
var i = [1,2,3,4,5]
for(var x in i){
console.log(x)//输出 0,1,2,3,4(下标);
console.log(i[x])//输出 1 2 3 4 5;
}
======================================================
//循环字符串
1.for of 循环
var i = 'nihao'
for(var x of i){
console.log(x)//输出 n i h a o;
}
2.for in 循环
var i = 'nihao'
for(var x in i){
console.log(x)//输出 0,1,2,3,4(下标);
console.log(i[x])//输出 n i h a o;
}
=========================================================
//循环对象
1.for of 循环
var i = {
name :'你好',
age:18,
}
//把属性名转换为数组以数组的方式遍历
for(var x of Object.keys(i)){
console.log(x)// name ;age
console.log(i[x])//'你好' ;18
}
2.for in 循环
for(var x in i){
console.log(x)// name ;age
console.log(i[x])//'你好' ;18
}
数组的浅拷贝和深拷贝
//浅拷贝 地址拷贝
var i = [1,2,3]
var k = i;
k[0] = 100;
consile.log(i,k);//k[0] = i[0] = 100;
//深拷贝 定义一个新数组,遍历数组加值;地址不同,改值互不影响;
var i = [1,2,3];
var k = [];
for(var h = 0;h<i.length;h++){
k[h] = i[h];
}
//对象也一样 -------------------------------
//深拷贝
var i = {
name:'nihao',
age:12,
hobby:'playGame',
way:function(){
console.log('你好');
}
}
var j = {};
for(var l in i){
j[l] = i[l];
}
console.log(i,j);
//浅拷贝
var i = {}
var j = i;
i['name']='zaijain';
console.log(i,j);
构造函数
1.构造函数里面常常会出现this this指向实例化对象
2.构造函数默认返回 this对象;
3.用构造函数可以在对象初始化的时候添加对象属性;
//1.构造函数首字母大写;
//内置构造函数 Object ; String ; Number ; Boolean;
function Mana(attrN, value){
this[attrN] = value;
//默认 return this;
}//this指向实例化时调用该构造函数的对象;
function way(){
console.log('你好');
}
var i = new Mana('way',way);
console.log(i);
//关键字 new 实例化对象;
工厂模式
//在函数里面 new一个对象;
function cre(){
var object = new Object();
return object;
}
//用一个变量来指向该对象;
var i = cre();
创建对象的几种模式
//1.字面值创建
var i = {};
//2.构造函数创建
function Student(name,age){
this.name = name;
this.age = age
}
var student1 = new Student('mana','18');
//3.内置构造函数;
var j = 'hello'
var he = new String(j);
//4.工厂模式
JSON数据
JSON数据格式:
{"id":"${clazzid}","name":"${clazzname}","major":"${clazzmajor}"}
//实际上是个对象;
var json = {
result: 'success',
data: [
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 349,
shopName: '商品名1'
},
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 699,
shopName: '商品名2'
},
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 1032,
shopName: '商品名3'
}
]
}
//json数据转字符串
JSON.stringify(json(json对象));
//json数据字符串转对象
JSON.parse(json(json类型的字符串));
//json数据在网页上显示--------重要。
var str = '<div class="shop-box">';
for (var i = 0; i < json.data.length; i++) {
str += '<div class="shop">' +
'<p>'+json.data[i].price+'</p>' +
'<p>'+json.data[i].shopName+'</p>' +
'</div>';
}
str +='</div>';
console.log(str);
document.write(str);
原型
谈谈你对原型的理解
面试回答:每个对象都有一个原型,构造函数的原型是prototype;所有(实例化)对象的原型是__proto__即[[prototype]];所有实例化对象的原型指向对应构造函数的原型;所有构造函数的原型(prototype)的原型(__proto__)指向构造函数object的原型(prototype),而object的原型(prototype)的原型指向null;所有构造函数的__proto__都指向内置构造函数Function的原型(prototype);
原型链:当对象使用一个方法或属性的时候,自己的属性里面没有该属性或方法,那么他就会去该对象的原型里面去查找;如果没有,就在该对象原型所指向的原型里面去找,如果都没有就放回undefined或报错;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zjy6TvHU-1633951794063)(F:\H5作业课件\javascript课件\JS初级笔记\自己笔记\原型与原型链.png)]
DOM文本对象模型
//获取元素 也可用document.querySelectorAll()获取全部
document.querySelector('#id');
document.querySelector('.class');
document.querySelector('标签名');
document.querySelector('标签名').innerHTML//可识别标签
var i = document.querySelectorAll('p');
i[0].style.color = 'red';
i[1].innerHTML = `<span>`+ `nihap`+ `</span>`+
`<p>`+ `nihap`+ `</p>`
DOM事件
三要素:
1.事件源 事件 事件处理函数
//点击事件
//html
<p class="nihao" style="cursor: pointer;">你好</p>
<div class="zaijian" style=" display: none; background-color: black; width: 100px; height: 100px;"></div>
//js
var j = document.querySelector('.zaijian');
document.querySelector('.nihao').onclick = function () {
if (j.style.display == 'none') {
j.style.display = 'block';
} else {
j.style.display = 'none';
}
}
操作符
1.in 操作符 判断属性或方法在对象里;
for( indexValue in obj)
2.逻辑运算符
(1)! 非 返回布尔
(2)&& 与 100&&200 返回200;
(3)|| 或 100||200 返回100;
3.一元运算符
(1)++ //前置 先运算在赋值
(2)--
(3)+(遇字符串就拼接) - * / %
4.三目运算符
条件?语句1:语句2 //真就语句1 假就语句2
var i = 0>1? 100:200 //返回200
5.比较运算符
(ALL) > , < ,<= ,>= != !==(判断值、类型不等) ==(是否相等) ===(类型、值是否相等)
用回调函数在构造函数原型添加属性或方法;
//以object为例在原型添加数组的reduce方法 !!!!以防忘记
var arr = [2,3,4];
Object.prototype.newReduce = function (func,ini){
if(ini ==null){
ini = 0;
}
this.forEach((x,index,arr)=>{
ini = func(ini,x,index,arr);
})
return ini;
}
var j = arr.newReduce((ini ,i,x,arrN)=>{
return ini+i;
});
console.log(j)
改变this指向
1. function.bind(obj)(参数)// 是函数作为对象时的方法,会把函数中this对象重新指向第一个参数(obj)再把后面的参数作为参数传给function运行;obj是对象以下也是
function x(x1,x2){
console.log(x1,x2,this);
}
x();
x.bind(Object)(2,12);
2. function.call(obj,参数1,参数2);//
function x(x1,x2){
console.log(x1,x2,this);
}
x();
x.call(Object,10,12);
3.function.apply(obj,[参数1,参数2]);
function x(x1,x2){
console.log(x1,x2,this);
}
x();
x.apply(Object,[1,3]);
//======================================
//bind不传参时即fn.bind(arr)是函数 不会执行函数fn 要执行必须再次调用 fn.bind(arr)();
//方法练习;
let arr = [3, 4, 2, 1];
function fn(...data) {
console.log(data);
return this;
}
console.log(fn.apply(arr, [100, 200]), fn.call(arr, 100, 200), fn.bind(arr)());
闭包
解释:闭包就是函数里面返回了函数,并在函数外面用到了函数里面的值;
搭建函数外面到函数里面的一个桥梁;
优点:可以保存数据
缺点:无法函数里面的变量释放内存,造成内存泄露;
var func = ()=>{
var i = 0;
return ()={
retuen i++;
};
}
var fuc2 = func();
定时器
1.setInterval(function(){
},参数2(间隔时间ms))//循环调用function
2.setTimeout(function(){
},参数2(延迟时间))//在延迟时间过了之后调用function只执行一次
date对象
//获取当前时间
var i = new Date();
var x = new Date('2021-08-11 9:00:00');
i.get....
// 获取当前时间戳 是指现在到1900年的毫秒值;
i.getTime()
//设置时间戳 需传入一个时间戳
i.setTime(x);
//设置未来时间
1.var x = new Date('2050-08-11 9:00:00');
2.var now = i.getTime()+ 4*24*60*60*1000 //未来四天后的时间戳,;
i.setTime(now);//设置 i的当前时间戳;
js单线程、同步、异步
js单线程:
同步:从上往下逐条执行代码;
异步:异步任务会在同步任务执行完后执行 分别有:
setInterval(()=>{
console.log('1000是每隔1秒执行该函数');
},1000)
setTimeout(()=>{
console.log('1000是延迟1秒执行该函数只执行一次');
},1000)
网页时钟效果
1.html
<div class="time"></div>
2.js
setInterval(()=>{
var i = new Date();
document.querySelector('.time').innerHTML = `${i.getHours().toString().padStart(2,0)}:${i.getMinutes().toString().padStart(2,0)}:${i.getSeconds().toString().padStart(2,0)}`;
},1000)
网页随机点名
//实现点击随机点名 2秒后停止
1.html
<button>随机点名</button>
<div class="Sname"></div>
2.js
var arr = ['nihao','zaijian','scacs','csacsazx','csacdiuchv'],ti = 0;
document.querySelector('button').onclick = function(){
var nam = setInterval(() => {
var i = Math.floor(Math.random()*arr.length);
document.querySelector('.Sname').innerHTML = arr[i];
ti +=200;
if(ti>2000){
console.log(ti);
clearInterval(nam);
}
}, 200);
}
网页倒计时
2.js
var fangxue = setInterval(()=>{
var future = new Date('2021-08-07 17:30:00')
var i = new Date();//future-i 返回的是毫秒
var hourse = Math.floor((future-i)/1000/60/60);
//分钟取整放回剩余分钟
var minute = Math.floor((future-i)/1000/60%60);
//秒钟取整放回剩余秒
var second = Math.ceil((future-i)/1000%60);
document.querySelector('.newtime').innerHTML = `距离放学还有:${hourse.toString().padStart(2,0)}:${minute.toString().padStart(2,0)}:${ second.toString().padStart(2,0)}`;
if(i== future){
clearInterval(fangxue);
}
},1000)
数据劫持
// 劫持json的data数据;
var json = {
result: 'success',
data: [
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 349,
shopName: '商品名1'
},
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 699,
shopName: '商品名2'
},
{
shopImgUrl: 'https://www.baidu.com',
oldPrice: 699,
price: 1032,
shopName: '商品名3'
}
]
}
var jsonData = json.data;
// 参数一是要劫持的对象 ;参数二是要劫持对象的属性;参数三是对象有 修改查看劫持对象的方法;
Object.defineProperty(json, 'data', {
get: () => {
// 每当查看json对象里面的data属性是调用该方法;不能再这个代码块 里面写查看json data属性的语句,否则死循环;
return jsonData;
},
set: (Newvalue) => {
//每当修改json的面的data是调用该方法;注意
jsonData = Newvalue;
}
})
json.data = ['nihao']
console.log(json.data)
正则表达式
定义:
/ 表达式 /属性值
var i = new RegExp('表达式','ig');
属性:
/ 表达式 /g(全局匹配)i(不区分大小写) m(多行匹配)
方括号[]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oRYBsBtW-1633951794067)(.\正则表达式方括号.jpg)]
//方括号里只匹配一个字符可以用量词限制匹配个数
//eg1:
var reg=/[1234567890][1234567890][1234567890]/g;
var str="12309u98723zpoixcuypiouqwer";
str.match(reg);//["123","987"]
//eg2:
var reg=/[ab][cd][d]/g;
var str="abcd";
str.match(reg);//["bcd"];
//eg3:
var reg=/[0-9A-Za-z][cd][d]/g;//相当于var reg=/[0-9A-z][cd][d]/g
var str="ab1cd";
str.match(reg);//["1cd"];
小括号()
var reg = /(adc|bwe)/;//匹配adc或bwe 只匹配|两边
元字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cwaZdCQ0-1633951794069)(.\01.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TTZ3n8Aj-1633951794072)(\03.png)]
量词
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kxXB0RUI-1633951794073)(\02.png)]
更多去看老师笔记
简洁版Vue原生代码实现数据修改截取
//html
<div id="box">
姓名:{{name}}
年龄:{{age}}
</div>
//js1
<script>
var i = new Vue({
el: '#box',
data: {
name: 'nihao',
age: 'zaijian'
}
})
setTimeout(function () {
i.data = {
name: '123',
age: 'zaijian'
}
}, 1000)
</script>
//js2
function Vue(obj) {
this.el = obj.el;
this.data = obj.data;
this.elinnerHTML = document.querySelector(this.el).innerHTML;
this.init();
this.watch();
}
Vue.prototype.init = function () {
var _this = this;
var r = this.elinnerHTML.replace(/\{\{(\w+)\}\}/g, function ($, $1) {
return _this.data[$1];
});
console.log(this.elinnerHTML, r)
document.querySelector(this.el).innerHTML = r;
}
Vue.prototype.watch = function () {
var muddle = this.data;
Object.defineProperty(this, 'data', {
get: function () {
return muddle;
},
set: function (value) {
muddle = value;
this.init();
}
});
}
以下是es6语法=========
let变量声明
//变量声明不会有变量提升
console.log(i)//报错;
let i = 0
//变量不会作为window属性;
//声明的变量只会在当前块级作用域{块级作用域}有效
//let 不能重复声明变量;
const常量声明
//声明常量,声明时必须赋值,赋值后不能更改;
//没有变量提升
//声明的变量所指向的地址不能被更改,但是地址所对应的数据可以更改
3.
const i = {
name:'nihao',
}
i.name = 'zaijian'
console.log(i)//zaijian
数组的解构声明
//不修改原数组,可实现数组深拷贝
let i = [100, 200, 300]
let [...j] = i;
console.log(j);
//let [a,b,c] = [100,200,300];
a = 100,b = 200, c = 300;
//可嵌套
let [a,[b,c]] = [100,[200,300]];
//可忽略
let [a[,c]] = [100,[200,300]];//100,300
//值交换
let a = 100,b=200;
[a,b] = [b,a];
//扩展运算符
let [a,...b] = [100,200,300];a = 100,b = [200,300]//数组
//函数传参
function nihao([i,j]){
console.log(i,j);
}
//======================
//函数(...j) 相当于([...j]);传入对象也一样;
function nihao(...j){
console.log(j);[1,2]
}
let x = [1,2];
nihao(x);
//付初始值
let [a=b,b] = []//报错先执行let a = b let b;
数组新增
1.arr.keys()
2.arr.values()
3.arr.entries()
4.let i = Array.of(参数) //创建数组
5.let j = Array.from(arrLike)//类似数组的对象转换为数组;
对象的解构
//可忽略
let {name} = {name:'nihao',age:18}
console.log(name);
//可嵌套
//name = 'nihao' mana1 = 'nihao' mana = undefinde;
let {name,mana:{mana1}} = {name:'nihao',mana:{mana1:'nihao'}}
let {name,mana:{a,b,c}} = {name:'nihao',mana:[1,2,3]}//a,b,c =1,2,3
//可扩展
let {...name} = {name:'nihao',mana:{mana1:'nihao'}}
//深拷贝
let i = {name:'nihao',age:18}
console.log({...i})
//函数传参
function ni({a,b}){
}
//====================
function ni(...j){
console.log(j)//[{x:100,y:200}]
}
ni({x:100,y:200});
//对象的合并 相同值覆盖
{...obj1,obj2}
//付初始值
let {a=b,b} = {a:100}//报错先执行let a = 100 let b,不执行 let a=b;
模块化解构
js
export let y = {
x: 14,
y: 'matchMedia',
}
<script type="module">
import { y } from './mo.js';
console.log(mo)
</script>
箭头函数
let i = ()=>{}
1.没有 arguments
2.定义是this就确定了--指向上级的作用域
3.简洁
对象新增的方法
获取对象键值,健名,键值对
//object.keys(obj)
//object.values(obj)
//object.entries(obj)
判断两数是否相等
Object.is(参数1,参数2)//
Object.is(NaN,NaN) true
对象的合并
let x = Object.assign(obj1,obj2)
//结构合并
{...obj1,...obj2};
Symbol
//新数据类型,定义Symbol 不相等 避免命名重复 常常用做变量名;
let i = Symbol('fu'(描述符));
//用作函数名
i = () => {
};
console.log(i)
//用作对象属性
let i = Symbol('i');
let j = Symbol('j') ;
let obj = {
[i]:'i',
}
obj[j] = 'j';
//方法
//1.Symbol.for
let s5 = Symbol.for('foo');
let s6 = Symbol.for('foo');
s5 === s6 // true
//2.Symbol.keyFor(s7)
let s7 = Symbol.for('register');//必须用for创
console.log(Symbol.keyFor(s7));//register
set集合数据结构
//不是数据类型
//定义 在定义的时候可传值 只能传数组
let i = new Set(1,2,3);//报错
let i = new Set([1, 2, 3, 4, x]);
//set对象的方法
set.add(值);//添加值;
set.has(x) //set:一个集合类型的数据 传入x查看集合是否有该数;有返回true
set.delete(x)//set:一个集合类型的数据 传入想要删除的数
set.size() //获取集合的成员个数;
Array.from(set数据)//把set数据转换为数组
//set 的遍历
set.forEach((v)=>{});
//set 实现数组去重
let se1 = new Set([1, 2, 3, 4, 5, 11, 2, 23, 1, 5, 4, 2])
//用解构赋值
let [...newArr] = se1;
//用Array.from方法把se1转换为数组;
let newArr = Array.from(se1);
console.log(newArr);
map数据结构
let i = new Map([['name','mana'],['fn',function(){}]])//存的类似键值对传入二维数组第一个是作为健名,第二个作为值;
//map方法
map.set(健名,键值);
map.get(健名);
map.has(健名);返回布尔值
map.clear();删除全部
map.forEach();遍历与数组一样;
//值的获取可以用 values,keys entries 等
同步与异步
1.同步是一行一行执行
2.异步需要等到同步任务执行完在执行; 而异步中微任务(promise本身不是微任务,then,catch才是),(async)先与宏任务(定时器)//注意async函数 本身是同步的,遇到await后面的代码就会是异步代码(await同行 后面的除外); 而promise中只有resolve 和 reflect是异步代码;
console.log('1');
setTimeout(() => {
console.log('4');//异步宏任务先执行
}, 0)
let p = new Promise(function (resolve, reject) {
reject('3');//异步微任务 相对宏先执行;
setTimeout(function () { //异步宏任务
console.log('5');
resolve('7');//异步任务中的异步后执行 reject执行后不执行
console.log('6');
}, 0)
})
p.then(function (data) {
console.log(data);
}, function (err) {
console.log(err);
})
console.log(2);
//结果123456
promise
//三种状态
1.一开始进入加载状态pending;
2.成功:fulfilled;
3.失败:fail;
//是内置构造函数;实例化必须传函数 函数参数 resolve('成功'),reject('失败')
//原型方法
//1.then 传函数 函数一 成功就执行,失败执行函数二;
//2.catch 当失败了执行catch
let p = new Promise(function (resolve, reject) {
//成功的时候执行resolve函数
resolve('你又行了');
//失败的时候执行reject函数
reject('错了');
})
// 当promise的状态为fulfilled时即成功时执行then的第一个传入的函数;
//当状态为fail时即失败的时候 then就执行第二个传入的参数;
p.then(function (data) {
console.log(data);
}, function (err) {
console.log(err);
})
//catch相当于then的第二个函数;
p.then(function (data) {
console.log(data)//你又行了
}).catch(function (err) {
console.log(err)//错了
});
//
let p1 = new Promise(function (resolve, reject) {
//成功的时候执行resolve函数
resolve('你又行了');
//失败的时候执行reject函数
reject('错了');
})
let p2 = new Promise(function (resolve, reject) {
//成功的时候执行resolve函数
resolve('你又行了');
//失败的时候执行reject函数
reject('错了');
})
3.let pAll = Promise.all([p1,p2]);
pAll.then(function(data){
//全部成功
})
//all rise 方法
let p1 = new Promise(function (resolve, reject) {
resolve({
data: {
name: 'ni',
age: 20,
}
});
})
let p2 = new Promise(function (resolve, reject) {
resolve({
data: {
heig: 200,
w: 120
}
});
})
let p3 = new Promise(function (resolve, reject) {
reject('失败');
})
//all
let Pall = Promise.all([p1, p2, p3]);//全部成功才会成功
Pall.then((data) => {
console.log(data)
}, (err) => {
console.log(err);//失败
});
//race
let Psome = Promise.race([p3, p1, p2]);//有一个成功就会执行then
Psome.then((data) => {
console.log(data);
}).catch((err) => {
console.log(err)//失败
})
//判断是否有值, Local Storage--储存方式;
localStorage.setItem('name', 'mana');//存入值;
let data = localStorage.getItem('name');
let newdata = localStorage.getItem('newdata');
console.log(newdata);
if (localStorage.getItem('newdata')) {
console.log(newdata);
} else {
let Pall = Promise.all([p1, p2, p3]);
Pall.then((data) => {
console.log(data)
localStorage.setItem('newdata', data);
console.log(localStorage.getItem('newdata')[1])
})
}
async函数
//定义本身是同步代码 await 下面的代码才是异步代码,await同行的是同步代码
1.
let i = async () => {
let x = await 223;
console.log(x)
}
2.
async function fn() {
let x = await 11;
console.log(x)
}
//执行 直接调用就行了
fn();
async函数 与promise 搭配使用
async function fn() {
let x = await new Promise((resolve, reject) => {
//请求数据
resolve('data');
});
//x 为请求返回的数据;
console.log(x);
//多次请求
let x1 = await new Promise((resolve, reject) => {
resolve('data');
});
console.log(x1);
}
//执行请求;
fn();
类class
//定义
class animetion {
//构造函数
constructor(type, name) {
//初始化写入属性;
this.type = type;
this.name = name;
}
//在原型上写方法
getData() {
console.log(Object.values(this).join(''));
}
}
//在原型上写方法 2
animetion.prototype.getname = function () {
console.log(this.name);
}
let i = new animetion('shazi', 'wangxin');
console.log(i)
i.getData();
i.getname();
类的继承
class animetion {
//构造函数
constructor(type, name) {
//初始化写入属性;
this.type = type;
this.name = name;
}
//在原型上写方法
getData() {
console.log(Object.values(this).join(''));
}
}
//继承
class wangxin extends animetion {
constructor(type, name, hoppy, age) {
super(type, name);
this.age = age;
this.hoppy = hoppy;
}
getData() {
let _this = this;
setTimeout(() => {
console.log(`喜欢吃${_this.hoppy}的${_this.type + _this.name}只有${_this.age}岁`);
}, 4000)
}
}
let newW = new wangxin('shazi', 'wangxin', '奥利给', '10');
newW.getData();
自定义属性
<div data-属性名></div>
js
<获取></获取>
div.dataset.属性名
事件循环
});
console.log(x1);
}
//执行请求;
fn();
## 类class
```js
//定义
class animetion {
//构造函数
constructor(type, name) {
//初始化写入属性;
this.type = type;
this.name = name;
}
//在原型上写方法
getData() {
console.log(Object.values(this).join(''));
}
}
//在原型上写方法 2
animetion.prototype.getname = function () {
console.log(this.name);
}
let i = new animetion('shazi', 'wangxin');
console.log(i)
i.getData();
i.getname();
类的继承
class animetion {
//构造函数
constructor(type, name) {
//初始化写入属性;
this.type = type;
this.name = name;
}
//在原型上写方法
getData() {
console.log(Object.values(this).join(''));
}
}
//继承
class wangxin extends animetion {
constructor(type, name, hoppy, age) {
super(type, name);
this.age = age;
this.hoppy = hoppy;
}
getData() {
let _this = this;
setTimeout(() => {
console.log(`喜欢吃${_this.hoppy}的${_this.type + _this.name}只有${_this.age}岁`);
}, 4000)
}
}
let newW = new wangxin('shazi', 'wangxin', '奥利给', '10');
newW.getData();
自定义属性
<div data-属性名></div>
js
<获取></获取>
div.dataset.属性名
事件循环