js手写题
call apply bind
let obj = { name: "hello" };
let t = {
fn: function (a, b) {
console.log(this);
console.log(a);
console.log(b);
return a
},
};
Function.prototype._call = function(context, ...arg){
context = context || window
context._fn = this
let res = context._fn(...arg)
delete context._fn
return res
}
t.fn._call(obj, 1, 2)
// apply ...arg接收参数不同
Function.prototype.myApply = function (context, arg) {
context = context || window;
context.__fn = this;
var res = context.__fn(...arg);
delete context.__fn;
return res;
};
t.fn.myApply(obj, [1, 2])
Function.prototype._bind = function(context, ...arg){
context = context || window
context._fn = this
return function(...inner){
let res = context._fn(...arg, ...inner)
delete context._fn
return res
}
}
let fn = t.fn._bind(obj, 'hh')
new
function Person(a){
this.a = a
// return {haha: 444}
}
function _new(Ctor, ...arg){
if(typeof constructor !== 'function'){
throw TypeError
}
let obj = Object.create(Ctor.prototype)
let res = Ctor.apply(obj, arg)
return res && typeof res === 'object' ? res : obj
}
var p = _new(Person, 2)
console.log(p)
ajax
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.responseText)
}
}
xhr.open('get', 'https://www.baidu.com/gethaha')
xhr.send({data: 'haha'})
闭包
function fn(){
let _a = 22
return function(){
return _a
}
}
let a = fn()
a() // 可访问到内部变量_a
防抖 节流
// 防抖, 时间内触发, 取消定时后-重新计时
function debounce(fn, waitTime) {
let timer;
return function () {
if (timer) {
clearTimeout(timer);
timer = null;
}
timer = setTimeout(fn, waitTime);
};
}
// 节流 水龙头滴水,时间结束后-再计时
function throttle(fn, waitTime) {
let timer;
return function () {
if (!timer) {
fn(); // 立即调用
timer = setTimeout(() => {
timer = null;
fn();
}, waitTime);
}
};
}
window.addEventListener(
"scroll",
debounce(() => { // 连续触发场景,debounce 最终一次, throttle 1秒一次
console.log("11");
}, 1000)
);
promise
status pendding
fulfilled
rejected
execute(resolve, reject) 执行函数
then(onResolved, onRejected)
异步 then 先收集回调函数,resolve种遍历执行回调函数(可多个then)
function _Promise(execute){
this.status = 'pendding'
this.value = null
this.reason = null
this.resolveCallbackArr = []
this.rejectCallbackArr = []
const resolve = (value) => {
if(this.status == 'pendding'){
this.value = value
this.status = "fulfilled"
this.resolveCallbackArr.forEach( fn => fn())
}
}
const reject = (reason) => {
if(this.status == 'pendding'){
this.reason = reason
this.status = 'rejected'
this.rejectCallbackArr.forEach( fn => fn())
}
}
execute(resolve, reject)
this.then = function(onFulfilled, onRejected){
if(this.status == "fulfilled"){
onFulfilled(this.value)
}
if(this.status == "rejected"){
onRejected(this.reason)
}
if(this.status == 'pendding'){
this.resolveCallbackArr.push(() => {
onFulfilled(this.value)
})
this.rejectCallbackArr.push(() => {
onRejected(this.reason)
})
}
}
}
let test = new _Promise(function(resolve,reject){
setTimeout(() => {
resolve({code: "000000"})
}, 1000)
})
test.then((data)=>{
console.log(data)
})
深拷贝
assign 浅拷贝
JSON.parse(JSON.stringify(data))
递归
柯里化
js类继承
js数据类型 8种
String Number Boolean Null Undefined Symbol Bigint Object
array方法
slice(s,e) start~end shift() 首为删 splice(0,2,'3') 0开始删2个,加一个'3' concat() 连接多个 flat(Infinity) 拍平
string方法
slice(s,e) e可为负数 substring() ,自动交换小到大,无负数 substr(s, l)