1.预编译,执行上下文
function method(a,b,c){
console.log(a,b,c);
var a = ‘a’;
var b = function b(){};//函数表达式
(function a(){});//函数表达式
(function b(){});//函数表达式
function c() {};
console.log(a,b,c);
}
method(1,2,3);
// 预编译
// 第一步,确定形参
// {
// a:1,
// b:2,
// c:3,
// }
// 第二步,确定函数声明
// {
// a:1,
// b:2,
// c:3,
// c:fn
// }
// 若遇到同名数据,则进行覆盖
// {
// a:1,
// b:2,
// c:fn
// }
// 第三步,查看函数中有哪些变量
// {
// a:1,
// b:2,
// c:fn
// a:undefined
// b:undefined
// }
// 若遇到同名数据,则直接忽略,而并非覆盖
// {
// a:1,
// b:2,
// c:fn
// }
//第一次的输出
//{
// a:1,
// b:2,
// c:fn
// }
//第二次的输出
//{
// a:‘a’,
// b:fn b,
// c:fn c
// }
2.多选框纯css控制选中与未选中
.checkbox input{
display: none;
}
.checkbox span{
display: inline-block;
user-select: none;
}
.checkbox span::before,
.checkbox span::after{
content: ‘’;
position: absolute;
left: 0;
top:50%;
transform: translateY(-50%);
width: 1em;
height: 1em;
border: 1px solid #ccc;
border-radius: 3px;
transition: 0.2s;
}
.checkbox span::after{
width: 0.6em;
height: 0.6em;
left:0.2em;
background: #579ef8;
border-color: #579ef8;
opacity: 0;
}
.checkbox input:checked~span::before{
border-color: #579ef8;
}
.checkbox input:checked~span::after{
opacity: 1;
}
文字颜色渐变
5.图形交融.container{
width: 320px;
height: 320px;
background: #fff;
border-radius: 50%;
position: relative;
/* 对比度 */
filter: contrast(20);
}
.blackball{
width: 120px;
height: 120px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
background: #000;
border-radius: 50%;
filter: blur(5px);
}
.redball{
position: absolute;
width: 60px;
height: 40px;
background: #f00;
left: 50%;
top:90px;
border-radius: 50%;
transform: translate(-50%);
/* 模糊 */
filter: blur(5px);
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
font-size: 3em;
cursor: pointer;
/* border: 3px solid #000; */
position: relative;
}
.front,
.back{
width: 100px;
height: 100px;
transition: 1s;
color: #fff;
}
.front{
background: #f40;
}
.back{
background: #008c8c;
}
.back{
transform: rotateY(180deg);
}
.container:hover .front{
transform:rotateY(-180deg);
}
.container:hover .back{
transform:rotateY(0deg);
}
.front,
.back{
backface-visibility: hidden;
position: absolute;
left: 0;
top: 0;
}
.container{
/* 设置透视,近大远小,表示人的的眼睛距离屏幕有800个像素 */
perspective: 800px;
}
// 解析
//parseInt(‘1’,0)---->1
//parseInt(‘2’,1)---->NaN
//parseInt(‘3’,2)---->NaN
//parseInt第二个参数是进制,2~36,传的0,表示没有传递,当成十进制;穿的非零的无效进制,为NaN;二进制中不存在3
10.事件注册
点击
function a(){
console.log(1);
return function b(){
console.log(2);
}
}
var btn = document.querySelector(‘button’);
btn.onclick = a();//(1),表示a函数的执行结果
btn.onclick = a;//(2),表示直接执行a函数
// 若注释(1),执行结束后不会有输出,当用户点击button按钮时,输出1
// 若注释(2),执行结束后会输出1,当用户点击button按钮时,输出2
11.删除数组中的偶数
//方法一
var nums = [2,2,4,7,3,8];
for(var i = 0; i < nums.length; i++){
if(num[i] % 2 === 0){
nums.splice(i,1);
}
i–;
}
console.log(nums);
//方法二
var nums = [2,2,4,7,3,8];
for(var i = nums.length-1; i > 0; i–){
if(num[i] % 2 === 0){
nums.splice(i,1);
}
}
console.log(nums);
12.defer与async的区别
默认:解析页面,遇到js,获取js,获取完直接执行jjs,执行完js后继续解析完页面
defer:解析页面,遇到js,获取js同时继续解析,解析完页面执行domContentLoaded事件,解析完毕运行js
async:解析页面,遇到js,获取js同时继续解析,解析一部分,获取到js,执行js,执行完js接着解析完页面
13.表格表头排序小三角
14.常识
(1)JavaScript中的数字在计算机内存中占8Byte(字节)
8 位 = 1 Byte
1024 Byte = 1KB
1024 KB = 1 MB
1024 MB = 1 GB
javascript中数字类型只有双精度浮点数,64位,也就是8字节
(2)数组方法
//splice会改变原数组
var nums = [1, 2, 3];
nums.splice(1,1);
console.log(nums);//[1,3]
//concat不会改变原数组
var num1 = [1,2,3];
var num2 = [4,5,6];
var newNum = num1.concat(num2);
console.log(num1);//[1,2,3]
console.log(num2);//[4,5,6]
console.log(newNum);//[1,2,3,4,5,6]
//sort会改变原数组
var num = [1,2,3];
var newNums = num.sort(
function(a,b){
return a-b;
}
);
console.log(num)//[3,2,1]
//pop会改变原数组,末尾删除
var number = [1, 2, 3, 4];
nums.pop();
console.log(number);//[1,2,3]
(3)this指向
// this指向谁取决于这个函数是如何调用的而不是取决于这个函数如何声明
//this直接通过fun()调用,直接调用指向window,window中没有a,则为undefined
var obj = {
a:1,
b:function(){
alert(this.a)//弹出undefined
}
};
var fun = boj.b;
fun();
(4)函数的返回结果给变量
function Foo(){
var i = 0;
return function(){
console.log(i++)
}
}
var f1 = Foo();//函数的返回结果给f1
var f2 = Foo();
f1();
f1();
f2();
//0 1 0
(5)布尔判定与短路规则
布尔判定:
假:false,null,undefined,‘’,0,NaN
真:其他
运行结果
返回结果为能确定结果的最后一个数据
console.log(2 && 4);//4
console.log(2 || 4);//2
(6) 赋值运算符
1)找到变量a的内存地址,准备赋值
2)运算右侧代码,得到要赋值的数据
3)将右侧运算的数据放入到之前的地址中
4)返回整个表达式的结果为右侧运算的数据
var a = {
n: 1
};
var b = a;
a.x = a = {
n:2
};
console.log(a.x);//undefined
console.log(b.x);//{n:2}
(7)深度克隆
function deepClone(value){
//非原始值的情况
//数组类型
if(Array.isArray(value)){
var clone = [];
for(var i = 0; i < value.length; i++){
clone[i] = deepClone(value[i]);
}
return clone;
}
//对象类型
if(typeof value === ‘object’ && value !== null){
var clone = {};
for(var key in value){
clone[k] = deepClone(value[key]);
}
return clone;
}
//原始值类型
return value;
}
console.log(deepClone(1));//1
var o1 = [1,2,{a:1,b:[3,2,1]}];
var o2 = deepClone(o1);
console.log(o2);//[1,2,{a:1,b:[3,2,1]}]
console.log(o2 === 01);//false
(8)数据传递
function increase(a){
a++;
}
var a = 1;
increase(a);
increase(a);
console.log(a);//1
function increase(a){
a={
n:2,
};
}
var a = {
n:1,
};
increase(a);
increase(a);
console.log(a);//n:1
(9)两数不借助第三个变量交换
var a = 6;
var b = 5;
//不借助第三个变量完成交换
//第一种,只能针对数据
a = a + b;
b = a - b;
a = a - b;
console.log(a,b);//5,6
//第二种,异或相同取0,不同取1,只能针对数据
a = a ^ b;
b = a ^ b;
a = a ^ b;
console.log(a,b);//5,6
//第三种,es6中的解构
[b,a] = [a,b];
console.log(a,b);//5,6
(10)选择器权重
(x,y,z)
x:id选择器的数量
y:类,伪类,属性选择器的数量
z:元素,伪元素的数量
(11)空白折叠
display:inline;容易产生空格
布局时一般选择浮动,弹性,网格布局
(12)加法运算
1)判断是否均为为原始类型
i 是原始类型(判断是否有字符串)
a. 有字符串
都转为字符串,进行拼接
b. 无字符串
都转为数字,进行加法运算(一侧有NaN,结果为NaN)
2)判断是否含有对象类型
ii 含有对象类型
a. 调用valueOf(),转原始类型
b. 若转不成,在调用toString()
c. 报错
1+1//2
‘1’+1//‘11’
NaN+1//NaN
NaN+‘1’//‘NaN1’
null+1//1
null+‘1’//‘null1’
[1]+1//‘11’
[1,2]+[1]//‘1,21’
[1]+{n:1}//‘1[object Object]’
null+undefined//NaN
(13)对象属性的遍历顺序与书写顺序
js会先将数字属性进行升序排序并提前(内存空间进行占位);字符串按照原本书写顺序,目的是对浏览器的内存管理,提高运行效率
var obj = {
p2: ‘aaa’,
2: ‘aaa’,
1: ‘aaa’,
p1: ‘aaa’,
};
for(var key in obj){
console.log(key);//1 2 p2 p1
}
(14)&运算
// 判断数字x是否是2的n次方
// x>0且为整数
function isPowerOf2(x){
return (x & (x -1)) === 0;//二进制转换,2的n次方的二进制中必有一个1
}
console.log(2);//true
(15)js label
//js label
ref:a = 1;
//标记语法,案例
outerLoop :for(var i = 0; i < 10; i++){
console.log(‘外层循环’);
for(var j = 0; j < 10; j++){
console.log(‘内层循环’);
// break;//只会结束当前循环,不会结束外层循环
//结束外层循环
break outerLoop;
}
}
(16)数字
11//11
.11//0.11
11.//11
011//9(0开头,当作8进制)
080//80(8为无效8进制数字,就当成十进制)
0o11//9(0o开头,当作8进制)
0o80//报错(必须为8进制有效数字)
0b11//3(0b开头,当作2进制)
0x11//17(0x开头,当作16进制)
11e2//1100(科学计数法11*10^2)
11.toString()//报错
11 .toString()//‘11’
(17)单身狗
// nums数组中包含一个或多个正整数
// 其他数字都出现两次
// 只有一个数字出现一次
//找出只出现一次的数字
//异或支持交换律;相同数字异或=0;0异或任何数字=任何数字
//第一种,传统方式
function uniqueNumber(nums){
var result = 0;
for(var i = 0; i < nums.length; i++){
result = result ^ nums[i];
}
return result;
}
console.log(uniqueNumber([1,3,1,2,2,7,3]))//7
//第二种,es6
function uniqueNumber(nums){
return nums.reduce((a,b)=>a^b,0);
}
console.log(uniqueNumber([1,3,1,2,2,7,3]));//7
(18)属性名的类型
var a = {};
b = {
key:‘b’
};
c = {
key:‘c’
};
a[b] = 123;
// a[‘[object Object]’] = 123;
a[c] = 456;
// a[‘[object Object]’] = 456;
console.log(a[b]);//456
// console.log(a[‘[object Object]’]);
//1.变量的值作为属性的名字
var a = {};
var b = ‘abc’;
a[b] = 123;
// a.abc = 123;
console.log(a.abc)
//2.对象的属性会转为字符串(String,Symbol)
var arr = [];
arr[1] = 1;
arr[‘1’ = 3];
console.log(arr[1]);//3
//3.调用对象的toString()方法
var obj1 = {
a:1,
b:2,
};
var obj2 = {
c:3,
d:4,
}
console.log(obj1.toString());//[object Object]
console.log(obj2.toString());//[object Object]
(19)随机颜色
//随机颜色
//rgb(x,y,z)
function randomColor(){
var r = Math.floor(Math.random()*256);
var g = Math.floor(Math.random()*256);
var b = Math.floor(Math.random()*256);
return rgb(${r},${g},${b})
;
}
console.log(randomColor());
//#xxxxxx
function randomColor(){
return ‘#’ + Math.random().toString(16).substring(2,8);
}
console.log(randomColor());
(20)无法预测的大数运算
console.log(Number.MAX_SAFE_INTEGER + 1 ===Number.MAX_SAFE_INTEGER + 2);//true
var START = 2**53;
var END = START + 100;
for (var i = START; i < END; i++){
console.log(‘loop’);//无法预测
}
//js的数字存储,64位浮点数;符号,指数,尾数(52位,前边有个1);二进制数字53位;2的53次方为9007199254740991=Number.MAX_SAFE_INTEGER;最大的安全整数
(21)判断对象中存在的属性
function hasProperty(obj,key){
//in关键字判断该属性在不在该对象中,同时可以在原型链上查到
return key in obj;
}
var obj = {
a:undefined
};
Object.defineProperty(obj,‘c’,{
enumerable:false,
value:1,
});
console.log(hasProperty(obj,‘c’));//true
//错误写法1
function hasProperty(obj,key){
return obj.key !== undefined;
}
//错误写法2
function hasProperty(obj,key){
return obj[key] !== undefined;
}
var obj = {
a:undefined
};
Object.defineProperty(obj,‘c’,{
enumerable:false,
value:1,
});
console.log(hasProperty(obj,‘toString’));//true
//貌似正确
function hasProperty(obj,key){
return Object.keys(obj).includes(key);
}
var obj = {
a:undefined
};
console.log(hasProperty(obj,‘a’));//true
console.log(Object.keys(obj));//[‘a’]
//错误写法3
function hasProperty(obj,key){
return Object.keys(obj).includes(key);
}
var obj = {
a:undefined
};
Object.defineProperty(obj,‘c’,{
enumerable:false,
value:1,
});
console.log(obj.c);//1
console.log(Object.keys(obj));//[‘a’]
console.log(hasProperty(obj,‘c’));//false
//貌似正确
function hasProperty(obj,key){
return obj.hasOwnProperty(key);
}
var obj = {
a:undefined
};
Object.defineProperty(obj,‘c’,{
enumerable:false,
value:1,
});
console.log(hasProperty(obj,‘c’));//true
//错误写法4
function hasProperty(obj,key){
return obj.hasOwnProperty(key);
}
var obj = {
a:undefined
};
Object.defineProperty(obj,‘c’,{
enumerable:false,
value:1,
});
console.log(hasProperty(obj,‘toString’));//false
console.log(obj.toString);//[Function:toString]
(22)数组去重
//数组去重
//原始值使用严格相等比较
//对象值递归比较所有属性,属性数量与属性名称必须一致
//数组中的对象均为plain object
function uniqueArray(arr){
var result = [];
for (var i = 0; i < arr.length; i++){
var isFind = false;
for(var j = 0; j < result.length; j++){
if (equals(result[j],arr[i])){
isFind = true;
break;
}
}
if(!isFind){
result.push(arr[i]);
}
}
return result;
}
function equals(v1,v2){
}
console.log(null == undefined);//true
console.log(null === undefined);//false
console.log(NaN === NaN);//false
console.log(Object.is(NaN === NaN));//true
console.log(
{
id:1,
name:‘a’
} ===
{
id:1,
name:‘a’
}
)//false
//方式一,使用es6的set和展开运算符去重
function uniqueArray(arr){
return […new Set(arr)];
}
console.log(uniqueArray([
{
id:1,
name:‘a’
},
{
id:1,
name:‘a’
}
]))
//结果为:
// {
// id:1,
// name:‘a’
// },
// {
// id:1,
// name:‘a’
// }
//方式二:不使用标准库,完全手写去重过程
function uniqueArray(arr){
var result = [];
for (var i = 0; i < arr.length; i++){
var isFind = false;
for(var j = 0; j < result.length; j++){
if (result[j] === arr[i]){
isFind = true;
break;
}
}
if(!isFind){
result.push(arr[i]);
}
}
return result;
}
(23)阴影
/* box-shadow针对整个盒子做阴影 */
img{
box-shadow: 0 0 10px #000;
}
/* drop-shadow针对这个区域中的像素点,严丝合缝的阴影选择drop-shadow */
img{
filter: drop-shadow(0 0 10px #000);
}
(24)轮播图
//移动轮播图到第几个位置
function moveTo(index){
doms.carousel.style.transform = translateX(-${index}00%)
;
//去除当前选中的指示器
var active = document.querySelector(‘.indicator span.active’);
active.classList.remove(‘active’);
//重新设置要选中的指示器
doms.indicators[index].classList.add(‘active’);
}
doms.indicators.array.forEach(function(item,i) {
item.onclick = function(){
moveTo(i);
}
});
无缝切换原理:最后一张图后复制第一张图;第一张图前复 制最后一张图
var doms = {
carouselList: document.querySelector(‘.carousel-list’),
arrowLeft: document.querySelector(‘arrow-left’),
arrowLeft: document.querySelector(‘arrow-right’),
indicators: document.querySelectorAll(‘.indicator span’),
};
var curIndex = 0;//记录当前是第几张
//移动轮播图到第几个位置
function moveTo(index){
doms.carouselList.style.transform = translateX(-${index}00%)
;
doms.carouselList.style.transition = ‘.5s’;
//去除当前选中的指示器
var active = document.querySelector(‘.indicator span.active’);
active.classList.remove(‘active’);
//重新设置要选中的指示器
doms.indicators[index].classList.add(‘active’);
curIndex = index;
}
doms.indicators.array.forEach(function(item,i) {
item.onclick = function(){
moveTo(i);
};
});
function init(){
//复制第一张图片
var first = dom.carouselList.firstElementChild.cloneNode(true);
//复制第一张图片
var last = dom.carouselList.lastElementChild.cloneNode(true);
//将第一张放到末尾
doms.carouselList.appendChild(first);
//将最后一张放到开头
doms.carouselList.insertBefore(last,doms.carouselList.firstElementChild);
//设置最后一张复制图为绝对定位
last.style.position = ‘absolute’;
last.style.transform = ‘translateX(-100%)’;
}
init();
function leftNext(){
if(curIndex === count - 1){
doms.carouselList.style.transform = translateX(100%)
;
doms.carouselList.style.transition = ‘none’;
//强制渲染(读取尺寸就会引起回流,重新渲染)
doms.carouselList.clientHeight;
moveTo(0);
}else{
moveTo(curIndex + 1);
}
}
var count = doms.indicators.length;
function rightNext(){
if(curIndex === count - 1){
doms.carouselList.style.transform = translateX(100%)
;
doms.carouselList.style.transition = ‘none’;
//强制渲染
doms.carouselList.clientHeight;
moveTo(0);
}else{
moveTo(curIndex + 1);
}
}
dom.arrowLeft.onclick = leftNext;
dom.arrowRight.onclick = rightNext;
(25)函数防抖(电梯进人等待3秒)
function debounce(fn,delay){
var timerId;
return function(){
clearTimeout(timerId);
timerId = setTimeout(fn,delay);
};
}
(26)不使用计时器做动画
//计时器渲染帧(跳帧,空帧)
var x = 0;
setInterval(function(){
x++;
ball.style.left = x + ‘px’;
},16);
//H5新出的API
function raf(){
requestAnimationFrame(function(){
//设置动画,例如改变位置
raf();//继续设置下一帧
});
}
(27)数字格式化
var str = 10000000000;
//10,000,000,000
var result = str.replace(/(?=\B(\d{3})+$)/g,‘,’);
(28)动画暂停效果
@keyframes rotate{
0%{
transform: rotateY(0deg);
}
100%{
transform: rotateY(-360deg);
}
}
/* 从旋转到暂停 */
.container{
animation: rotate 20s linear infinite;
}
.container:hover{
animation-play-state: paused;
}
/* 从暂停到 旋转*/
.container{
animation: rotate 20s linear paused infinite;
}
.container:hover{
animation-play-state: running;
}
(29)文本溢出
/* 单行文本溢出 /
p{
white-space:nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/ 多行文本溢出 */
p{
display: -webkit-box;
-webkit-line-clamp:5;
-webkit-box-orient:vertical;
}
(30)bind和call
//手写bind
Function.prototype.myBind = function(ctx){
var fn = this;
return function(){
return fn.apply(ctx,arguments);
};
};
function fn(a,b){
console.log(this,a,b);//{},2,3
}
var newFn = fn.myBind({});
newFn(2,3);
//简单案例
function fn(a,b){
console.log(this,a,b);//{},2,3
}
var newFn = fn.bind({});
newFn(2,3);
//手写call(1)
Function.prototype.myCall = function(
ctx,
…args
){
console.log(this);//[Function:method]
ctx.fn = this;
ctx.fn(…args);
delete ctx.fn;
};
function method(a,b){
console.log(this,a,b);//{},2,3
return a+b;
}
method.myCall({},2,3);
//手写call(2)
Function.prototype.myCall = function(
ctx,
…args
){
console.log(this);//[Function:method]
var key = Symbol(‘temp’);
ctx[key] = this;
ctxkey;
delete ctx.fn;
};
function method(a,b){
console.log(this,a,b);//{fn:[Function:method]},2,3
return a+b;
}
method.myCall({},2,3);
//手写call(3)
Function.prototype.myCall = function(
ctx,
…args
){
console.log(this);//[Function:method]
var key = Symbol(‘temp’);
Object.defineProperty(ctx,key,{
enumerable:false,
value:this
})
ctxkey;
delete ctx.fn;
};
function method(a,b){
console.log(this,a,b);//{},2,3
return a+b;
}
method.myCall({},2,3);
//手写call(4),最理想化的代码
Function.prototype.myCall = function(
ctx,
…args
){
console.log(this);//[Function:method]
ctx = (ctx === null || ctx === undefined) ? globalThis : Object(ctx);
var key = Symbol(‘temp’);
Object.defineProperty(ctx,key,{
enumerable:false,
value:this
})
var result = ctxkey;
delete ctx.fn;
return result;
};
function method(a,b){
console.log(this,a,b);//{},2,3
return a+b;
}
method.myCall({},2,3);
//简单案例
function method(a,b){
console.log(this,a,b);//{[Symbol(temp)]:[Function:method]},2,3
return a+b;
}
method.call({},2,3);
(31)监听元素(页面底部加载)
var loading = document.querySelector(‘.loading’);
//建立观察者
var ob = new IntersectionObserver(function(entries){
var entry = entries[0];
if(entry.isIntersecting && !isLoading){
more();
console.log(“加载”)
}
},{
thresholds:0.1
});
//观察
ob.observe(loading);
(32)Flip动画
F:First,记录起始位置
L: Last,记录结束位置
I: Invert,反转元素到起始位置
P:Play,播放动画回到结束位置
(33)青蛙跳台阶
//青蛙跳台阶问题,每次只能跳一阶或两阶
//n=1:f(n)=1
//n=2:f(n)=2
//n=3:f(n) = f(n-1)+f(n-2)
function f(n){
if(n <= 0){
throw new Error(‘台阶数量必须大于0’);
}
if(n <= 2){
return n;
}
var last1 = 2,last2 = 1;
for(var i = 3; i < n; i++){
// last1 = last2 + (last2 = last1);
last1 = last1 + last2;
last2 = last1 - last2;
}
return last1;
}
console.log(f(6));//13
(34)环形旋转
(35)按钮边框旋转效果
.button{
color:#0ebeff;
font-size: 24px;
background: #000;
border: none;
outline: none;
z-index: 1;
border-radius: 10px;
/* outline: 4px solid #fff; */
position: relative;
overflow: hidden;
}
.button::before{
content: ‘’;
position: absolute;
background: #f40;
width: 200%;
height: 200%;
z-index: -2;
left: 50%;
right: 50%;
transform-origin: 0 0;
animation: rotate 3s infinite linear;
}
.button::after{
content: ‘’;
position: absolute;
/* background: #008c8c; */
background: #000;
width: calc(100% - 4px);
height: calc(100% - 4px);
left: 2px;
top: 2px;
border-radius: 10px;
z-index: -1;
}
@keyframes rotate{
to{
transform:rotate(1turn);
}
}
(36)Material文本框
button::before{
content: ‘’;
position: absolute;
width: 20px;
height: 20px;
/* background: #f40; /
/ 径向渐变 */
background: radial-gradient(
circle at 0 0 ,
transparent,
transparent 20px,
#000 20px);
bottom: 0;
left: -20px;
}
button::after{
content: ‘’;
position: absolute;
width: 20px;
height: 20px;
/* background: #f40; /
/ 径向渐变 */
background: radial-gradient(
circle at 100% 100% ,
transparent,
transparent 20px,
#000 20px);
top: 0;
right: -20px;
}
随薪所欲
(39)手写Promise.all //手写Promise.allPromise.myAll = function(proms){
let res,rej;
const p = new Promise((resolve,reject)=>{
res = resolve;
rej = reject;
});
//设置p的状态
const result = [];
let count = 0;//数量
let fulFilledCount = 0;//完成的数量
for(const prom of proms){
const i = count;
count++;
Promise.resolve(prom).then(data=>{
//将成功的数据汇总到result
result[i] = data;
//判断是不是全部完成
fulFilledCount++;
if(fulFilledCount === count){
res(result);
}
},rej);
}
if(count === 0){
res(result);
}
return p;
}
Promise.all([]).then((datas) =>{
console.log(datas);//[]
});
// Promise.all([1,2,3]).then((datas) =>{
// console.log(datas);//[1,2,3]
// });
(40)卡片反转
.card{
/* 3D旋转效果 */
perspective: 500px;
}
.face{
transition: 0.5s;
/* 背面可见度隐藏 */
backface-visibility: hidden;
}
.card:hove .face{
/* 逆时针旋转180度 */
transform: rotateY(-180deg);
}
.back{
transform: rotateY(-180deg);
backface-visibility: hidden;
transition: 0.5s;
}
.card:hove .back{
transform: rotateY(0);
}
随薪所欲
// ?位置应该为什么才能输出true
var a = ? ;
console.log(
a == 1 &&
a == 2 &&
a == 3
);
//解答
var a = {
n: 1,
valueOf:function(){
return this.n++;
}
} ;
console.log(
a == 1 &&
a == 2 &&
a == 3
);//true
//例1
var obj = {};
console.log(obj.valueOf());//{}
console.log(obj.toString());//[object Object]
console.log(obj == 1);//false
//例2
var obj = {};
console.log(obj.valueOf());//{}
console.log(obj.toString());//[object Object]
console.log(obj == ‘[object Object]’);//true
//例3
var obj = {
valueOf:function(){
return 1;
}
};
console.log(obj == 1);//true
(42)undefined在js中不是关键字,是window的属性
//注:以下内容是在浏览器的控制面板输入的
//在js中,undefined不是关键字,是window的一个属性,但它是一个只读属性
window.undefined//undefined
window.undefined = 1//1
//可能会出现的问题
function m(){
var undefined = 1;
var a = undefined;
console.log(a);//1
}
//赋值undefined不允许这样写
var a = undefined//undefined
赋值undefined允许这样写
var a = void 0//undefined
// void 表达式;这样书写只是为了制造一个undefined出来
a//undefined