function type_fn(a){ let result; if(typeof a == 'object'){ result = (a instanceof Array)?'Array':'object' }else{ result = typeof a } return result } 说明:鉴于 数组和对象和null的typeof都是object 因此基于typeof 另外须要instanceof判断区分 //补充 也能够用:Object.prototype.toString.call(a).slice(8,-1)
function Class(){ this.slogan = function(){ console.log('我来自班级1'); } } function Classmate(name){ this.name = function(){ console.log('我是'+name) } } Classmate.prototype = new Class(); //实例化 var peo1 = new Classmate('jerry'); peo1.name(); //我是jerry peo1.slogan(); //我来自班级1
建立一个新的对象 this指向新的对象 对this赋值 执行代码 返回this
/** * 原型链继承的例子 * 功能: 1.获取元素改变或者获取他的innerhtml。 * 2.添加事件。 */ //构造函数 function Elem(id){ this.elem = document.getElementById(id); }; //在其原型上添加方法 Elem.prototype.html = function(val){ var elem=this.elem; if(val){ elem.innerHTML = val; return this; //链式调用 }else{ return elem.innerHTML; } } Elem.prototype.on = function(type,fn){ var elem=this.elem; elem.addEventListener(type,fn); return this; } var div=new Elem('app'); div.html(`<h1>你好javascript</h1>`).on('click',function(){ alert('我是天使') }) 原文连接:https://blog.csdn.net/qq_24675001/article/details/82054443
当JavaScript执行过程进入新函数时,这个函数内被声明的全部变量都会被移动导到函数最开始的地方。这种现象叫作提高。且被提高的只有变量的声明。javascript
函数执行时会先建立当前的上下文环境,其中这两点会产生“变量提高”的效果php
做为构造函数时的执行 指向构造函数的对象css
做为对象属性时的执行 指向对象html
做为普通函数时的执行 指向window前端
call bind apply 从新把this指向新对象java
var i for (i = 0; i < 10; i++) { (function (i) { var a = document.createElement('a') a.innerHTML = i + '<br>' a.addEventListener('click', function (e) { e.preventDefault() alert(i) }) document.body.appendChild(a) })(i) }
* 自由变量 * 做用域链,即自由变量的查找 * 闭包的两个场景
// 闭包实际应用中主要用于封装变量,收敛权限 // 即把变量隐藏起来,不让外面拿到和修改 function isFirstLoad() { var _list = [] return function (id) { if (_list.indexOf(id) >= 0) { return false } else { _list.push(id) return true } } } // 使用 var firstLoad = isFirstLoad() firstLoad(10) // true firstLoad(10) // false firstLoad(20) // true // 在 isFirstLoad 函数外面,根本不可能修改掉 _list 的值
同步会阻塞代码 而异步不会 alert 是同步 setTimeout 是异步 eg: console.log('1'); setTimeout(function(){ console.log('2'); },200) console.log('3'); ------------- console.log('1') alert('2') console.log('3');
jq源码里面利用了js程序的单线程 写了setTimeout(function(){})来解决 等页面加载完; ------------------ console.log(1); setTimeout(function(){ console.log(2) },0) console.log(3) setTimeout(function(){ console.log(4) },1000) console.log(5) >> 1 3 5 2 4
定时任务: setTimeout setInverval 网络请求: ajax请求 动态<img>加载 事件绑定
function time(){ var date = new Date(); var year = date.getFullYear(); var month = date.getMonth()+1; var day = date.getDate(); return year+'-'+num_fn(month)+'-'+num_fn(day); } function num_fn(num){ return num>=10? num : '0'+num }
function randomAtr(){ return Math.floor(Math.random()*1000000000) //或者 //var num = Math.random()+''; //return num.slice(2,13) }
function forEach_fn(obj,fn){ var key; if(obj instanceof Array){ arr.forEach(function(item, index){ fn(index, item)//遍历数组全部的元素 }) }else{ for(key in obj){ fn(key, obj[key]) } }
}ajax
DOM树形结构json
建立型api:createElement
,createTextNode
,cloneNode
和createDocumentFragment
后端
页面修改型API
修改页面内容的api主要包括:appendChild
,insertBefore
,removeChild
,replaceChild
。api
节点查询型API
document.getElementById
document.getElementsByTagName
document.getElementsByName
document.getElementsByClassName
document.querySelector和document.querySelectorAll:经过css选择器来查找元素,注意选择器要符合CSS选择器的规则,使用的深度优先搜索来获取元素
节点关系型api
1.父关系型api
2.子关系型api
3.兄弟关系型api
元素属性型apisetAttribute
:根据名称和值修改元素的特性eg:element.setAttribute(name, value); getAttribute
:返回指定的特性名相应的特性值,若是不存在,则返回null或空字符串.
property 只是一个JS对象的属性的修改
Attribute 是对html标签属性的修改
navigator.userAgent 加正则匹配
href 完整的 URL。 protocol 当前 URL 的协议。 host 主机名和当前 URL 的端口号。 hostname 当前 URL 的主机名。 pathname 当前 URL 的路径部分。 port 当前 URL 的端口号。 hash hash。从井号(#)开始)。 search 参数。从问号(?)开始的。
function bindEvent(elem,type,selector,fn){ if(fn == null){ fn = selector; selector = null; } elem.addEventListener(type,function(e){ var target; if(selector){//有代理 target = e.target; if(target.macthes(target)){ fn.call(target,e)//从新指定this 并传参e } }else{//无代理 fn(e); } }) }
沿着DOM树形结构,一层层网上冒泡, 一直到 最顶端或者出现阻止冒泡命令 e.stopPropagation(); 冒泡的应用 代理
事件委派
1.建立ajax对象
2.接收服务器
3.发送请求
4.接收返回值
var oAjax = new XMLHttpRequest(); oAjax.open("GET","text.json",false); oAjax.send(); oAjax.onreadystatechange(function(){ if(oAjax.readyState == 4){ if(oAjax.status == 200){ console.log(oAjax.responseText) } } })
0开头
未初始化 尚未调用open()方法;1开头
载入 已调用open()方法,正在发送请求2开头
载入完成 send()方法完成,已收到所有响应内容3开头
解析 正在解析响应内容4开头
完成 响应内容解析完成,能够再客户端调用5开头
服务器错误 1. 服务器请求头修改 2. 重定向代理 3. jsonp
jsonp跨域 原生实现: <script> var script = document.createElement('script'); script.type = 'text/javascript'; // 传参并指定回调执行函数为onBack script.src = 'http://www.....:8080/login?user=admin&callback=onBack'; document.head.appendChild(script); // 回调执行函数 function onBack(res) { alert(JSON.stringify(res)); } </script>
get 安全性差 容量低 有缓存 经过url传 通常用于获取数据 post 安全性高 容量高 无缓存 通常用于用户注册
cookies
sessionStrorage
localStrorage
localStorage.setItem("saveData", JSON.stringify(setData) ); //存值 补充:存储前先用JSON.stringify()将json对象转字符串 localStorage.getItem("saveData”) //取值 补充:JSON.parse(ss) 将json字符串转为 json格式 localStorage.removeItem("saveData”);//删值
浏览器根据DNS服务器获得域名的IP地址 向这个IP的机器发送https/https请求 服务器收到、处理并返回请求 浏览器获得返回内容
window.onload:页面的所有资源加载完才会执行,包括图片、视频等 DOMContentLoaded:DOM渲染完便可执行,此时图片、视频尚未加载完
性能优化: 多使用内存、缓存或其余方法 减小cpu计算、减小网络 加载资源优化: 1静态资源的合并压缩 2静态资源缓存 3使用CDN让资源加载更快 4使用SSR后端渲染,数据直接输出到HTML中 渲染优化: 1.CSS放前面 JS放后面 2.懒加载(图片懒加载、下拉加载更多) 3.减小DOM查询,对DOM查询作缓存 4.减小DOM操做,多个操做尽可能合并在一块儿执行 5.事件节流 6.尽早执行操做(如DOMContentLoaded)
1 局部处理 meta标签中的 viewport属性 ,initial-scale 设置为 1 rem 按照设计稿标准走,外加利用transfrome 的scale(0.5) 缩小一倍便可; 2 全局处理 meta标签中的 viewport属性 ,initial-scale 设置为 0.5 rem 按照设计稿标准走便可
名字 | 特性说明 |
---|---|
var | 变量; 能重复声明; 函数级; 顶层对象的属性; 不限制修改 |
let | 变量; 不能重复声明; 块级; 不属于顶层对象的属性; 可修改 |
const | 声明和赋值必须是同时进行; 常量; 不能重复声明; 块级; 不属于顶层对象的属性; "不"可修改[ 实际上并不是彻底不可修改。const声明建立一个值的只读引用,对于基本类型不可修改,但若是是复合类型时,只要不修改引用,修改里面的值是能够的 ]; |
代码演示: console.log(k_name); //变量提高;输出undefined var k_name = "jerry"; console.log(k_name);//输出jerry console.log('1',k_age);//不会变量提高;在定义以前报错不能用 let k_age = "12"; console.log('2',k_age); //const基础类型时 const may_class = 3; may_class = 4;//基础类型时 报错 //const复杂类型时 const all_class = [1,2,3]; all_class[0] = 9; //不报错 console.log(all_class);//修改为功 》[9, 2, 3]
var url = "http://witmax.cn/index.php?key0=0&key1=1&key2=2"; // 返回url的拼接对象 function parseQueryString(argu) { var str = argu.split('?')[1]; var result = {}; var temp = str.split('&'); for (vari = 0; i < temp.length; i++) { var temp2 = temp[i].split('='); result[temp2[0]] = temp2[1]; } return result; //url上的所有参 } // 拓展一下 对页面url操做, 只有一个参 那么查找url上的参数并返回值, 若是有两个参数查找更新或删除参数 function urlSearch(argu ,newValue) { var str = window.location.search.slice(1); var result = {}; var temp = str.split('&'); for (vari = 0; i < temp.length; i++) { var temp2 = temp[i].split('='); result[temp2[0]] = temp2[1]; } return result; //url上的所有参 if (newValue !== undefined) { if (newValue !== null) { result[argu] = newValue;//更新值 }else { delete result[argu];//删除值 } // 更新参数后从新拼接 并替换url的连接 var str = ''; for(k in ee){ str += (k + '=' + ee[k] + '&'); } str = str.replace(/&$/,''); // var newUrl = window.decodeURIComponent(argu.split('?')[0]+'?'+str); var newUrl = window.location.href.split('?')[0]+'?'+str; window.history.pushState(null, document.title,newUrl); // return newUrl; }else{ return result[argu]; } }
if([] == false){ alert(1)} //在比较前false转成0 [].toString()转成了空字符串 空字符串转成0, ;因此true if({} == false){ alert(2)}//在比较前false转成0, {}.toString()转成"[object Object]" 不等 if([]){ alert(3)} //引用类型(数组 对象 函数)的比较并不是值的比较:两个对象保含一样的属性及相同的值 它们是不相等的。 各个因此元素彻底相等的两个数组也不相等。 if([1] == [1]){ alert(4)} if({x:1} == {x:1} ){ alert(4)}
引用类型的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等 eg:
var a = []; var b = a; //变量b引用同一个数组 b[0] = 1; console.log(b); // [1] console.log(a); // [1] a === b; //true: a和b引用同一个数据,所以它们相等 ###### 给定一个整数数组,找出其中两个数相加等于目标值
var twoSum = function(nums, target) { var cbArr = []; for(var i = 0; i< nums.length; i++){ if(cbArr.indexOf(i) == -1){ //除去已经在结果里面的 避免重复 for(var k = 0; k< nums.length; k++){ if((i !== k) && (nums[i]+ nums[k] == target)){ cbArr.push(i,k); } } } } return cbArr; };
eg: 输入: s = "lrloseumgh", k = 6 输出: "umghlrlose" var reverseLeftWords = function(s, n) { return s.slice(n).concat(s.slice(0,n)) };
function Foo(){ getName = function(){alert(1)}; return this; } Foo.getName = function(){alert(2)}; Foo.prototype.getName = function(){alert(3)}; var getName = function(){alert(4)}; function getName(){alert(5)}; Foo.getName(); getName(); Foo().getName(); getName(); new Foo().getName(); 答案---- //2 4 1 1 3
function fn(a) { console.log(a) var a = 123; console.log(a) function a() {} console.log(a) var b = function() { console.log('bb','1') } console.log(b) b(); function b() { console.log('bb','2') } } fn(1) -------------------------- a的分析: 进入fn 虽然带参数a进去 可是 进到函数 1 最开始a有声明式函数,会直接挂载在函数下,因此第一个打印是function; 2 第一个打印后立刻就给a赋值了123, 因此第二个打印是123; 3 下一行 a的声明式函数比2执行还早 因此不影响 第三个打印是123; -------------------------- b的分析: 1 b无论属于谁打印确定是function; 2 最开始b有声明式函数,会直接挂载在函数下,而后var 从新赋值了b的函数 因此 输出是 答案:function 123 123 function bb 1
var i= 10; function a(){ i = 20; console.log(i); // 20; for(var i=0; i<6;i++){ console.log(i) // 0-5 } console.log(this.i); //10 :window.i 外部环境不能访问内部环境中的任何变量和函数 console.log(i); //6 : 当前的局部变量在循环时被赋值为6 } a(); console.log(i) //10 :window.i 外部环境不能访问内部环境中的任何变量和函数
想法:写个闭包每次返回函数都带参累加,知道参数没有再也不执行函数 则返回累加的和。
先写个暴力概念版 只要我写得够多就能'知足'题目要求:
function add(a){ let sum = a; return function count_fn1(b){ sum +=b; return function count_fn1(c){ sum +=c; return function count_fn1(d){ sum +=d; return sum; }; }; } } add(1)(2)(3)(4)//10 全然不顾灵活不灵活拓展不拓展~ 老子就是干
不 咱们不能仅苟且的活着!要灵活要自由~
function add(a){ let sum = a; return function count_fn(b){ sum +=b; return count_fn(b); } } //改为递归 是能够灵活执行多少次函数达到累加。问题 输出的也是函数 没有把累计的值输出出来呀!
这时咱们要了解一个知识点:当咱们直接对函数使用alert()
或console.log()
时,函数的toString()
方法会被调用。并且函数的toString()方法是能够复写的
最终版:
function add(x) { var sum = x; var tmp = function (y) { sum = sum + y; return tmp; }; tmp.toString = function () { return sum; }; return tmp; } console.log(add(1)(2)(3)); //6
(() => { let x, y try { throw new Error() } catch (x) { (x = 1), (y = 2) console.log(x) } console.log(x) console.log(y) })() 答案: 1 undefined 2; 分析: catch 代码块接收参数 x。当咱们传递参数时,这与以前定义的变量 x 不一样 。这个 x 是属于 catch 块级做用域的且 默认了设置了等于1; 因此第一个打印1; 外面x依然没赋值;因此第二个打印`undefined`; y最开始let声明了,后面赋值了2,因此第二个打印2;
let person = { name: "Lydia" }; const members = [person]; person = null; console.log(members); 答案:[{ name: "Lydia" }]; 分析: 当设置两个对象彼此相等时,它们会经过 引用进行交互。可是当将`引用从一个变量分配至另外一个变量时`,实际上是执行了 复制 操做。 因此它们的引用并不一样
const settings = { username: "lydiahallie", level: 19, health: 90 }; const data = JSON.stringify(settings, ["level", "health"]); console.log(data); 答案:"{"level":19, "health":90}" 分析: [JSON.stringify(value[, replacer[, space]])](https://www.runoob.com/js/javascript-json-stringify.html)//老子还有第二第三个参数可传哦。 // 参数一:转换的值 // 参数二:替代者。用于转换结果的函数或数组。 // 参数三:控制空格 JSON.stringify的第二个参数是 替代者(replacer). 替代者(replacer)能够是个函数或数组,用以控制哪些值如何被转换为字符串。 若是替代者(replacer)是个 数组 ,那么就只有包含在数组中的属性将会被转化为字符串。在本例中,只有名为"level" 和 "health" 的属性被包括进来, "username"则被排除在外。 data 就等于 "{"level":19, "health":90}”.
懒加载: 图片的懒加载作法 都是把连接存放在 data-src中,监听onscroll时,一个个加载出来;
预加载:将全部所需的资源提早请求加载到本地,这样后面在须要用到时就直接从缓存取资源。
实现预加载的几种办法:
//使用img标签 <img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none”/> ------------ //js 使用Image对象 <script src="./myPreload.js"></script> //myPreload.js文件 var image= new Image() image.src="http://pic26.nipic.com/20121213/6168183 004444903000 2.jpg" ------------- //使用PreloadJS库 ------------- //使用XMLHttpRequest对象,虽然存在跨域问题,但会精细控制预加载过程 var xmlhttprequest=new XMLHttpRequest(); xmlhttprequest.onreadystatechange=callback; xmlhttprequest.onprogress=progressCallback; xmlhttprequest.open("GET","http://image.baidu.com/mouse,jpg",true); xmlhttprequest.send(); function callback(){ if(xmlhttprequest.readyState==4&& xmlhttprequest.status==200){ var responseText=xmlhttprequest.responseText; }else{ console.log("Request was unsuccessful:"+xmlhttprequest.status); } } function progressCallback(e){ e=e || event; if(e.lengthComputable){ console.log("Received"+e.loaded+"of"+e.total+"bytes") } }
1.break 跳出循环 2.continue 跳出本次循环,进入下次循环 3.return 停止跳出当前函数 4.throw 异常信息;停止程序抛出异常,可用于停止程序
定义:内存泄漏指任何对象在您再也不拥有或须要它以后仍然存在。
后果:变慢,崩溃,延迟大等:
哪些会形成:
dom
清空时,还存在引用避免策略
重绘:改变元素的样式。例如宽高颜色。
回流(重排):布局和样式都改变。
重排必定重绘,重绘不必定重排。
减小重绘和重排的方法:
DOM
查询cssText
或者className
一次性改变属性fragment
。