为了方便计算,时常将在元素中设置font-size值为62.5%javascript
var win_w=document.body.offsetWidth;
//定义变量
var fontSize;
if(win_w>640){
fontSize=24;
}else{
//若是浏览器窗口宽度(这里的实质就是body宽度)值小于320,取320
win_w=Math.max(320,win_w);
fontSize=win_w/320*12
}
//设置根元素的大小
document.getElementsByTagName('html')[0].style.fontSize=fontSize+'px';
复制代码
理想viewport宽度概括起来无非也就320、360、414css
清除浮动的四种方法:html
BFC触发方式:前端
bfc的做用:java
bfc处理:node
父级加:css3
子级加:git
参考文档github
主要区别在于: content 的包含问题,IE盒子模型content包含padding border ,此时的宽度就是content的宽度 标准盒子模型:content不包含其余任何部分。web
box-sizing:
6种原始数据类型:
引用类型:Object(Array 、Reg、 function等等)
类型 | typeof返回 |
---|---|
Undefined | undefined |
Null | object |
Boolean | boolean |
Number | number |
String | string |
Object | object |
Function | function |
instanceof: 用来判断A 是不是 B的实例,表达式为 A instanceof B,返回一个Boolean类型的值 instanceof 检测的是原型,只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪一种类型
Object.prototype.toString
console.log(Object.prototype.toString.call(123)); //[object Number]
console.log(Object.prototype.toString.call('123')); //[object String]
console.log(Object.prototype.toString.call(undefined)); //[object Undefined]
console.log(Object.prototype.toString.call(true)); //[object Boolean]
console.log(Object.prototype.toString.call({})); //[object Object]
console.log(Object.prototype.toString.call([])); //[object Array]
console.log(Object.prototype.toString.call(function(){})); //[object Function]
console.log(Object.prototype.toString.call(null)); //[[object Null]]
复制代码
// call apply的实现https://blog.csdn.net/qq_40479190/article/details/78324270
Function.prototype.call = function(context){
var context = context || window;
context.fn = this;
var args = [...arguments].slice(1);
var result = context.fn(...args);
delete context.fn;
return result;
}
Function.prototype.apply = function(context){
var context = context || window;
context.fn= this;
var result;
if(arguments[1]){
result = context.fn(...arguments[1]);
}else{
result = context.fn();
}
delete context.fn;
return result;
}
Function.prototype.bind = function (context) {
var that = this;
return function(){
return that.apply(context);
}
}
Function.prototype.bind2 = function(context){
var that = this;
var args = Array.prototype.slice.call(arguments,1);//arguments不是真实的数组,因此不能直接调用slice方法,须要用这个方法
return function(){
var argslist = [...arguments];//第二参数是调用bind函数后返回的函数再调用的时候传入的参数
return that.apply(context,[...args,...argslist]);//之因此也要用return是由于原函数可能有返回值
}
}
复制代码
var fs = require('fs');
var readFile = function(fileName){
return new Promise((resolve, reject) => {
fs.readFile(fileName,(error, data) => {
if(error){
reject(error);
}else{
resolve(data);
}
});
});
}
var gen = function* (){
var f1 = yield readFile('/etc/sdfsdf');
var f2 = yield readFile('/etc/sdfsdf');
console.log(f1.toString());
}
var genFn = gen(); // 调用方法
genFn.next(); // {value:'sdfdf',done:true}
// 改写成async函数
var asyncReadfile = async function(){
var f1 = await readFile('/etc/sdfsdf');
var f2 = await readFile('/etc/sdfsdf');
}
asyncReadfile();
复制代码
async function fn(args){
// ...
}
//等同于
function fn(args){
return spawn(function* (){});
}// spawn为自动执行器
function spawn(genF){
// genF为generator函数
return new Promise((resolve, reject) => {
var gen = genF();// generator函数调用
function step(nextF){
// 封装的执行器函数
try{
var next = nextF();
}catch(e){
return reject(e);
}
// 没有返回错误判断generator的返回结果
if(next.done){
// 若是next.done为true表示generator已经执行完了
return resolve(next.value);
}
// 若是没有执行完,则执行Promise.resolve(next.value)生成一个Promise对象而后继续递归调用
Promise.resolve(next.value).then((v) => {
step(() => {
return gen.next(v);
});
}, (err) => {
step(() => gen.throw(e));
});
}
step(() => gen.next(undefined));
});
}
复制代码
function compose(){
var args = arguments;
var start = args.length -1 ;
return function(){
var i = start;
var result = args[start].apply(this,arguments);
while (i--) result = args[i].call(this, result);
return result;
}
}
复制代码
函数防抖:
在事件被触发n秒后再次执行回调,若是在n秒内又被触发,则从新计时(函数防抖就是法师发技能的时候要吟唱,技能读条没完再按技能就会从新读条)
应用场景:
// 防抖debounce
// 初版
function debounce(func, wait){
var timeout;
return function(){
clearTimeout(timeout);
timeout = setTimeout(func, wait);
}
}
// this
function debounce(func,wait){
let timeoutNumber;
return function() {
let that = this;
clearTimeout(timeoutNumber);
timeoutNumber = setTimeout(function(){
func.applay(that);
},wait);
}
}
// 可能在执行的过程带事件,因此须要传递参数
function debounce(func,wait){
var timeoutNumber;
return function() {
let args = arguments;
clearTimeout(timeoutNumber);
timeoutNumber = setTimeout(() => {
func.apply(this,args);
},await);
}
}
// 当即执行,一开始就执行下来
function debounce(func,wait, immediate) {
var timeout;
var result;
return function(){
var that = this;
var args = arguments;
if (timeout) {
clearTimeout(timeout);
}
if(immediate){
var callNow = timeout; // 有表示已经执行过了
timeout = setTimeout(() => {
timeout = null;
}, wait);
if(callNow){
result = func.applay(that,args);
}
} else {
timeout = setTimeout(() => {
result = func.applay(that,args);
}, wait);
}
return result; // 函数的返回值
}
}
// 取消
function debounce(func,wait, immediate) {
var timeout;
var result;
var debound = function(){
var that = this;
var args = arguments;
if (timeout) {
clearTimeout(timeout);
}
if(immediate){
var callNow = timeout; // 有表示已经执行过了
timeout = setTimeout(() => {
timeout = null;
}, wait);
if(callNow){
result = func.applay(that,args);
}
} else {
timeout = setTimeout(() => {
result = func.applay(that,args);
}, wait);
}
return result; // 函数的返回值
}
debound.cancel = function(){
clearTimeout(timeout);
timeout = null;
};
return debound;
}
复制代码
函数节流:
规定在一个单位时间内,只能触发一次函数,若是这个单位时间内触发屡次函数,只有一次生效(我的理解:函数节流就是fps游戏的射速,就算一直按着鼠标射击,也只会在规定射速内射出子弹。)
// 利用时间戳来实现节流函数
function throttle(func,wait){
var previous=0;
var that = 0;
return function(){
var now=+ new Date();
args = arguments;
if(now - previous > wait){
func.apply(that, args);
previous = now;
}
}
}
const throttle2 = function(fn, delay) {
let preTime = Date.now()
return function() {
const context = this
let args = arguments
let doTime = Date.now()
if (doTime - preTime >= delay) {
fn.apply(context, args)
preTime = Date.now()
}
}
}
// 利用定时器来实现
function throttle(func,wait){
var timeout;
return function(){
var args = arguments;
if(!timeout){
timeout = setTimeout(() => {
time = null;
func.apply(this, args);
},wait);
}
}
}
const throttle = function(fn,delay) {
let timer = null
return function() {
const context = this
let args = arguments
if(!timer) {
timer = setTimeout(() => {
fn.apply(context,args)
clearTimeout(timer)
},delay)
}
}
}
//第三版
function throttle(func,wait){
var timeout,context,args,result;
var previous = 0;
var later = function(){
previous = + new Date();
timeout = null;
func.apply(context, wait);
}
return function(){
var now = + new Date();
var remaintime = wait - (now - previous);
context = this;
args = arguments;
if(remaintime <= 0 || remaintime > wait){
if (timeout){
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context,args);
} else if(!timeout){
timeout = setTimeout(later, remaintime);
}
}
}
function throttle(method, mustRunDelay) {
let timer,
args = arguments,
start;
return function loop() {
let self = this;
let now = Date.now();
if(!start){
start = now;
}
if(timer){
clearTimeout(timer);
}
if(now - start >= mustRunDelay){
method.apply(self, args);
start = now;
}else {
timer = setTimeout(function () {
loop.apply(self, args);
}, 50);
}
}
}
function throttle(fn,wait){
let timeout,
args,
start;
return function (){
args = arguments;
let that = this;
let now=Date.now();
if(!start){
start = now;
}
if(timeout){
clearTimeout(timeout);
}
}
}
复制代码
let a = {
age: 1
}
let b = Object.assign({}, a);
a.age = 2;
console.log(b.age)// 1
复制代码
let a = {
age: 1
}
b = {...a};
a.age = 2;
console.log(b.age);//1
复制代码
// 数组的浅拷贝: slice concat方法能够实现
function clone(arr){
var new_arr = arr.concat();
// var new_arr = arr.slice();
return new_arr;
}// 此方法只能拷贝没有嵌套对象或者数组的
// JSON.stringify();可是不能拷贝函数
// 浅拷贝的实现
function shalloeCopy(obj){
if(typeof obj !== 'object'){
return;
}
var newObj = obj instanceof Array ? [] : {};
for (var i in obj){
console.log(i);
if(obj.hasOwnProperty(i)){
newObj[i] = obj[i]
}
}
return newObj;
}
shalloeCopy({sdf:2,sdfdfd:1});
// 深拷贝
function deepClone(obj){
if(typeof obj !== 'object'){
return;
}
var newObj = obj instanceof Array ? [] : {};
for(var key in obj){
if(obj.hasOwnProperty(key)){
// 防止原型链上的属性
newObj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key]
}
}
return newObj;
}
复制代码
function extend(){
var args = arguments;
var target = args[0];
var objs;
var newObj;
for(var i = 0; i<args.length;i++){
objs = args[i];
if(objs != null){
for(var name in objs){
target[name] = objs[name];
}
}
}
}
复制代码
//偏函数 n 变成n-1元,只能一个个减小,m跟柯里化的区别
function partial(fn){
var args = [].slice.call(arguments, 1);
return function(){
var newArgs = args.concat([].slice.call(arguments));
return fn.applay(this,newArgs);
}
}
// 第二版
function partial(fn){
var args = [].slice.call(arguments,1);
return function(){
var position=0,len = args.length;
for(var i=0;i<len;i++){
args[i] = args[i] === _ ? arguments[position++] : args[i]
}
while(position < arguments.length) args.push(arguments[position++]);
return fn.apply(this, args);
}
}
// flatten扁平化
function flatten(){
let arr = arguments[0];
var result = [];
for(var i=0;i < arr.length;i++){
if(Array.isArray(arr[i])){
result = result.concat(flatten(arr[i]));
}else{
result.push(arr[i]);
}
}
return result;
}
// toString
function flatten(arr){
return arr.toString().split(',').map(item => +item);//+item是将字符串转化成数字,可是数组中有字符串的不行
}
// reduce实现
function flatten(arr){
return arr.reduce(function(prev,next){
return prev.concat(Array.isArray(next)?flatten(next):next)
}, []);
}
复制代码
// 初版
function curry(fn){
var args = [].slice.call(arguments, 1);//最外面的arguments,此处指的的是调用curry函数时候除了第一个函数外剩下的参数
return function(){
var newArgs = args.concat([].slice.call(arguments));//此处的arguments和前面的arguments不是一个,此处表示调用curry返回的函数再调用的时候又传的参数
return fn.apply(this,newArgs);
}
}
function add(a, b) {
return a + b;
}
var addCurry = curry(add, 1, 2);
addCurry() // 3
//或者
var addCurry = curry(add, 1);
addCurry(2) // 3
//或者
var addCurry = curry(add);
addCurry(1, 2) // 3
// 第二版
function sub_curry(fn) {
var args = [].slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat([].slice.call(arguments)));
};
}
function curry(fn, length){
length = length || fn.length; // 判断fn有多少形参
var slice = Array.prototype.slice; // arguments是非数组要调用该方法须要应用
return function(){
if(arguments.length < length){ // 表示调用柯里化后的函数参数没有传完
var combined = [fn].concat(slice.call(arguments)); // 柯里化后再调函数还须要的参数,与fn合成一个数组
return curry(sub_curry.apply(this, combined),length - arguments.length); // 总共须要的形参减去用过的形参
}else{
// 所调用的形参足够直接调用
return fn.apply(this,arguments);
}
}
}
// 通用性 适用性 前几个大量计算
// 1.参数复用性,
// http() https() get() getJson()
// 2。提早返回
var addEvent = function(el, type, fn ,capture){
if(window.addEventListener){
el.addEventListener();
}else{
el.atachEvent();
}
}
addEvent(p,click,callnack,true);
addEvent(p,click,callnack,true);
// 这样前面的代码调用了不少次
var addEvent = function(){
if(window.addEventListener){
return function(el, type, fn ,capture){
el.addEventListener();
}
}else {
return function(el, type, fn ,capture){
el.atachEvent();
}
}
}
var elBind = addEvent();
// 3.延迟执行 ,不定参数做为最后一次调用(空间换时间)
var allScore = 0;
var addScore = function(score){
// 对分数的判断 多少个三分 计算里程碑
allScore += score;
};
addScore(1);
addScore(2);
addScore(3); // 可是这样每次就加了
// 虚拟缓存,代理缓存
var curryScore = function(fn){
var _allScore = [];
return function(){
if(arguments.length === 0){
// 表示统计了
return fn.apply(null, _allScore);
}else{
_allScore = _allScore.concat([].slice.call(arguments));
}
}
};
var curryAddScore = curryScore(function(){
for(var i=0;i<arguments.length;i++){
allScore+=arguments[i]
}
});
curryAddScore(1);//0
curryAddScore(2);//0
curryAddScore();//3 不传参数的时候开始执行
复制代码
function each(obj, callback){
var length,i=0;
if(isArrayLik(obj)){
length = obj.length;
for(;i<obj.length;i++){
let isOut = callback.call(obj[i],i,obj[i]);
if(isOut === false){
break;// 跳出循环
}
}
}else{
for (i in obj){
let isOut = callback.call(obj[i],i,obj[i]);
if(isOut === false){
break;
}
}
}
return obj;
}
复制代码
// 第一种实现
function MyPromise(fn){
let self = this;
self.value = null;
self.error = null;
self.onFulfilled = null;
self.onRejected = null;
function resolve(value){
self.value = value;
self.onFulfilled(self.value);
}
function reject(err){
self.error = err;
self.onRejected(self.error);
}
fn(resolve,reject);
}
MyPromise.prototype.then = function(onFulfilled,onRejected){
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
}
module.exports = MyPromise;
复制代码
// 改进方案
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function Promise(fn){
let self = this;
self.value = null;
self.error = null;
self.status = PENDING;
self.onFulfilled = null;
self.onRejected = null;
function resolve(value){
if(self.status === PENDING){
setTimeout(function(){
self.status = FULFILLED;
self.value = value;
self.onFulfilled(self.value);
});
}
}
function reject(error){
if(self.status === PENDING){
setTimeout(function(){
self.status = REJECTED;
self.error = error;
self.onRejected(self.error);
});
}
}
fn(resolve,reject);
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
if (this.status === PENDING) {
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
} else if (this.status === FULFILLED) {
//若是状态是fulfilled,直接执行成功回调,并将成功值传入
onFulfilled(this.value)
} else {
//若是状态是rejected,直接执行失败回调,并将失败缘由传入
onRejected(this.error)
}
return this;
}
复制代码
const PENDING= 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
function Promise(fn){
let self = this;
self.value = null;
self.error = null;
self.status = PENDING;
self.onFulfilledCallbacks = [];
self.onRejectedCallbacks = [];
function resolve(value){
if(self.status === PENDING){
setTimeout(() => {
self.status = FULFILLED;
self.value = value;
self.onFulfilledCallbacks.forEach((callback) => {
callback(self.value)
});
},0);
}
}
function reject(error){
if(self.status === PENDING){
setTimeout(()=>{
self.status = REJECTED;
self.error = error;
self.onRejectedCallbacks.forEach((callback) => {
callback(slef.error);
});
},0);
}
}
fn(resolve,reject);
}
Promise.prototype.then = function(onFulfilled,onRejected){
if(this.status === PENDING){
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}else if(this.status === FULFILLED){
onFulfilled(this.value);
}else {
onRejected(this.error);
}
return this;
}
复制代码
function promiseAll(promises){
return new Promise(function(resolve, reject){
if(!(promises instanceof Array)){
throw new TypeError('promises must be an Array');
}
var len = promises.length;
var resolveCount = 0;
var resolvedArray = new Array(len);
for(var i=0;i<len;i++){
(function(i){
Promise.resolve(promises[i])
.then((value) => {
resolveCount++;
resolvedArray[i] = value;
if(resolveCount == len){
return resolve(resolvedArray);
}
},re => {
return reject(re);
}).catch((re) => {
console.log(re);
});
})(i)
}
});
}
复制代码
// 数组去重
function unique(arr){
var res = [];
for(var i=0;i<arr.length;i++){
// 注明,此处能够用数组方法includes 和indexOf方法来判断
for(var j=0;j<res.length;j++){
if(arrp[j] == res[j]){
break;
}
if(j === res.length){
res.push(arr[i]);
}
}
}
return res;
}
// 排序后再去重
function unique(arr){
var res = arr.filter(function(item,index,arr1){
return arr.indexOf(item) === index;
});
return res;
}
function unique(arr){
var obj = {};
return arr.filter(function(item,index,arr1){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[item] = true)
});
}
复制代码
var ws;
var lockReconnect = false;
var wsUrl = 'ws:xxx.1.1.1';
function initEventHandle() {
ws.onclose = function() {
reconnet();
};
ws.onerror = function(){
reconnect();
};
ws.onopen = function() {
heartChect.reset().start();
};
ws.onmessage = function () {
heartChect.reset().start();
};
}
function reconnect(url){
if(lockReconnect){
return;
}
lockReconnect = true;
setTimeout(function(){
createWebSocket(url);
});
}
复制代码