var 没有块级作用域,支持变量提升。
let 有块级作用域,不支持变量提升。不允许重复声明,暂存性死区。不能通过window.变量名进行访问.const 有块级作用域,不支持变量提升,不允许重复声明,暂存性死区。声明一个变量一旦声明就不能改变,改变报错。
实现一个new的伪代码
创建一个对象
连接原型
绑定this
返回该对象
function_new(){
let obj =newObject();let Con =[].shift.call(arguments);
obj.__proto__ = Con.prototype;let result = Con.apply(obj,arguments);returntypeof result ==='object'? result : obj
}
防抖函数:将多次触发变成最后一次触发;
functiondebounce(fn,wait){
let timer =null;returnfunction(){
let arg = arguments;if(timer){
clearTimeout(timer);
timer =null;}
timer =setTimeout(()=>{
fn.apply(this,arg)},wait)}}functionclg(){
console.log('clg')}
window.addEventListener('resize',debounce(clg,1000))
节流函数:将多次执行变成每隔一个时间节点去执行的函数
functionthrottle(fn,time){
let lastTime =null;returnfunction(){
let nowTime = Date.now();if(nowTime - lastTime > time ||!lastTime){
fn();
last = nowTime
}}}functionsayHi(){
console.log('hi')}setInterval(throttle(sayHi,1000),500)
call、apply区别
相同点:都是重定向this指针的方法。
不同点:call和apply的第二个参数不相同,call是若干个参数的列表。apply是一个数组
手写一个call方法
// 在这之前需要重新认识一下call方法的执行操作let mock ={
value :1};functionmockNum(){
console.log('value',this.value)}
mockNum.call(mock)// 改变了函数中this的指向,当前this指向了mock对象
转换一下实现方法就是
let mock ={
value:1;
mockNum:function(){
console.log('value',this.value)}}
mock.mockNum();
所以经过上面这个操作的演化而来的结果就是如下步骤:
1. 将函数设为一个对象的属性
2. 并将这个函数的属性调用
3. 删除该函数
Function.prototype.Mycall=function(context){
let obj = context || window;
obj.fn =this;// 这一步可以看做是this其实就指的当前函数。let args =[...arguments].slice(1);// 返回删除第一个元素的数组;let result = obj.fn(...args);// 调用函数delete obj.fn;return result;}// 操作一下let mock ={
value :1};functionmockNum(){
console.log('value',this.value);}
mockNum.Mycall(mock)// value 1
然后根据上面的方法再手写一个apply方法
Function.prototype.Myapply=function(context){
let obj = context || window;
obj.fn =this;let result = arguments[1]? obj.fn(arguments[1]): obj.fn([]);delete obj.fn;return result;}let mock3 ={
arr:[1,2,3,4,5],};functionarrx2(arr){
returnthis.arr.concat(arr).map((x)=> x *2);}
console.log("arrx2", arrx2.myApply(mock3));