1.call
var person = {
fullName: function(city, country) {
console.log(this,'this');
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
const result1 = person.fullName.call(true, "Seattle", "USA");
console.log(result1);
Function.prototype.myCall = function(obj,...params){
if(obj===null||obj===undefined) obj = globalThis;
if(typeof obj === 'number') obj = new Number(obj);
if(typeof obj === 'string') obj = new String(obj);
if(typeof obj === 'boolean') obj = new Boolean(obj);
const NAME = '0123456789_call';
obj[NAME] = this;
return obj[NAME](...params);
}
const result2 = person.fullName.myCall(true, "Seattle", "USA");
console.log(result2);
2.apply
var person = {
fullName: function(city, country) {
console.log(this,'this');
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
const result1 = person.fullName.apply(true, ["Seattle", "USA"]);
console.log(result1);
Function.prototype.myApply = function(obj,params){
if(obj===null||obj===undefined) obj = globalThis;
if(typeof obj === 'number') obj = new Number(obj);
if(typeof obj === 'string') obj = new String(obj);
if(typeof obj === 'boolean') obj = new Boolean(obj);
const NAME = '0123456789_apply';
obj[NAME] = this;
return obj[NAME](...params);
}
const result2 = person.fullName.myApply(true, ["Seattle", "USA"]);
console.log(result2);
3.bind
var person = {
fullName: function(city, country) {
console.log(this,'this');
return this.firstName + " " + this.lastName + "," + city + "," + country;
}
}
var person1 = {
firstName:"Bill",
lastName: "Gates"
}
const fun1 = person.fullName.bind(true,"Seattle","USA");
const result1 = fun1();
console.log(result1);
const fun2 = person.fullName.bind(true,"Seattle");
const result2 = fun2("USA");
console.log(result2);
Function.prototype.myBind = function(obj,...params1){
const that = this;
if(obj===null||obj===undefined) obj = globalThis;
if(typeof obj === 'number') obj = new Number(obj);
if(typeof obj === 'string') obj = new String(obj);
if(typeof obj === 'boolean') obj = new Boolean(obj);
return function(...params2){
const params = [...params1,...params2];
const NAME = '0123456789_bind';
obj[NAME] = that;
return obj[NAME](...params);
}
}
const fun3 = person.fullName.myBind(true,"Seattle","USA");
const result3 = fun3();
console.log(result3);
const fun4 = person.fullName.myBind(true,"Seattle");
const result4 = fun4("USA");
console.log(result4);
4.reduce
Array.prototype.myReduce = function (fun, init) {
const arr = this;
const len = arr.length;
if (len === 0) {
if (init !== undefined) return init;
throw new TypeError("Reduce of empty array with no initial value");
}
let index = null;
if (init) {
index = 0;
} else {
init = arr[0];
index = 1;
}
while (index < len) {
init = fun(init, arr[index], index, arr);
index++;
}
return init;
}
const arr = [];
const result = arr.myReduce(function (total, current, index, z) {
total += current;
return total;
},0)
console.log(result, 'myReduce');
5.实现sleep函数
function sleep(time){
const temp = Date.now();
while((Date.now()-temp) < time){
}
}
function fn1(){
console.log(123);
sleep(3000);
console.log(456);
}
fn1()
function sleep(time){
return new Promise((resolve,reject)=>{
setTimeout(()=>resolve(),time)
})
}
async function fn2(){
console.log(123);
await sleep(3000);
console.log(456);
}
fn2()
6.函数柯里化
function sun(a,b,c,d){
return a+b-c*d;
}
console.log(sun(1,2,3,4));
function kelihua(fn){
const len = fn.length;
let params = [];
function temp(...param){
params = params.concat(param);
if(params.length === len){
return fn(...params);
}
return temp;
}
return temp;
}
console.log(kelihua(sun)(1)(2)(3)(4));
console.log(kelihua(sun)(1)(2,3)(4));
7.获取URL参数
function getParams(){
const search = new URLSearchParams(location.search);
const iterator = search.entries();
const obj = {};
for(let [key,value] of iterator){
obj[key] = value;
}
console.log(obj);
return obj;
}
getParams()
8.new的实现
function MyObj(a,b){
this.a = a;
this.b = b;
}
const myobj = new MyObj(10,20);
console.log(myobj);
function codingNewMyObj(a,b){
const obj = {};
obj.a = a;
obj.b = b;
return obj;
}
console.log(codingNewMyObj(30,40));
9.Object.create实现
function myObjectCreate(obj){
if(typeof obj !== "object" || typeof obj !== "function"){
throw new Error("obj 需为对象或Function构造函数")
}
const t = {};
t.__proto__ = obj;
return t;
}
const temp = {a:123};
const temp1 = myObjectCreate(temp);
console.log(temp,temp.__proto__);
console.log(temp1);
10.防抖
function debounce(fn,delay){
let timer = null;
return function(...args){
timer && clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this,args);
timer = null;
}, delay);
}
}
11.节流
function throttle(fn,delay){
let start = Date.now();
return function(...args){
const end = Date.now();
if((end-start)>delay){
fn.apply(this,args);
start = end;
}
}
}
12.深拷贝
function copy(obj){
if(typeof obj !== "object" || obj === null){
throw new Error("obj需为对象");
}
function fn(data){
const temp = {};
const arr = Object.entries(data);
let t = null;
while(t = arr.shift()){
console.log(t,'t');
if(typeof t[1] === "object" && t[1] !== null){
temp[t[0]] = fn(t[1]);
}else{
temp[t[0]] = t[1];
}
}
return temp;
}
return fn(obj);
}
const obj1 = {a:1,b:{c:2},d:3};
const obj2 = copy(obj1);
console.log(obj1,obj2);
console.log(obj1 === obj2);
console.log(obj1.b === obj2.b);
13.手写ajax
function myAjax(method,url,data){
return new Promise((resolve,reject)=>{
const xhr = new XMLHttpRequest();
xhr.open(method,url,true);
xhr.send(data);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
resolve(xhr.responseText)
}
}
xhr.send()
})
}
14.手写Promise
15.instanceof
function myInstanceof(obj,OBJ){
while(obj.__proto__){
if(obj.__proto__ === OBJ.prototype){
return true;
}
obj = obj.__proto__;
}
return false;
}
class A{};
const a = new A();
console.log(myInstanceof(a,A));
console.log(myInstanceof(a,Object));
console.log(myInstanceof(a,String));
16.深度比较isEqual
function isEqual(obj1,obj2){
if(typeof obj1 !== "object" || typeof obj2 !== "object"){
return obj1 === obj2;
}
if(obj1 === obj2){
return true;
}
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if(keys1.length !== keys2.length){
return false;
}
for(let i = 0;i < keys1.length;i++){
if(keys1[i] !== keys2[i]){
return false;
}
if(!isEqual(obj1[keys1[i]],obj2[keys2[i]])){
return false;
}
}
return true;
}
const obj1 = {
a:1,
b:{
c:2,
d:3
}
}
const obj2 = {
a:1,
b:{
c:2,
e:3
}
}
console.log(isEqual(obj1,obj2));
17.jsonp
function myJsonp(url,callbackName){
return new Promise((resolve,reject)=>{
const script = document.createElement("script");
url = `${url}?callbackName=${callbackName}`;
script.src = url;
document.body.appendChild(script);
window[callbackName] = function(data){
document.body.removeChild(script);
resolve(data);
}
})
}
18.使用setTimeout实现setInterval
function mySetInterval(time){
function fn(){
setTimeout(()=>{
console.log(123);
fn();
},time);
}
fn();
}
mySetInterval(3000);
19.实现数组扁平化
function myFlat(arr,num){
let data = [];
num = num ? num : 1;
do{
data = [];
for(let i = 0;i < arr.length;i++){
const temp = Array.isArray(arr[i])?arr[i]:[arr[i]];
console.log(temp,'temp');
data.push(...temp);
}
arr = data;
}while(--num);
return data;
}
const arr = [1,[2,[3,4]]];
const arr1 = myFlat(arr,2);
console.log(arr,arr1,arr === arr1);
20.实现数组的push、filter、map
Array.prototype.myPush = function(...params){
for(let i = 0;i < params.length;i++){
this[this.length - 1] = params[i];
}
return this.length;
}
Array.prototype.myFilter = function(fn){
const arr = [];
for(let i = 0;i < this.length;i++){
if(fn(this[i])){
arr.push(this[i])
}
}
return arr;
}
Array.prototype.myMap = function(fn){
const arr = [];
for(let i = 0;i < this.length;i++){
arr.push(fn(this[i]));
}
return arr;
}
21.红黄绿循环打印
function fn(){
let num = -1;
function t(){
setTimeout(()=>{
if(num === 2){
num = -1;
}
num += 1;
switch(num){
case 0:
console.log("红");
t();
break;
case 1:
console.log("黄");
t();
break;
case 2:
console.log("绿");
t();
break;
default:
break;
}
},1000)
}
t();
}
fn();
22.用Promise实现异步加载图片
function lazyLodingImg(url){
return new Promise((resolve,reject)=>{
const img = new Image();
img.src = url;
img.onload = function(){
console.log("onload");
resolve(img);
}
img.onerror = function(){
console.log("onerror");
resolve(new Error("加载图片失败"))
}
})
}
console.log(123);
lazyLodingImg("https://file.ccmapp.cn/group1/M00/16/64/rApntl7CSdeAbpYqABArOjGaasg001.jpg");
console.log(456);
23.图片懒加载SDK
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box {
display: flex;
flex-wrap: wrap;
width: 600px;
margin: 0 auto;
font-size: 0;
}
.box>.img {
width: 200px;
vertical-align: top;
flex: 1;
display: flex;
flex-direction: column;
}
.img>img {
width: 200px;
}
</style>
</head>
<body>
<div class="box">
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/5e60c42e062e654f9113496900675294_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/75631b031ff234640edb416feecc9cc1_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/32e5ac518a46755c2fab839c11ba353f_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/552af0047051f642f511f83f89b1b8a9_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/957b39be46c507c7949a59e09d517107 (1)_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/17299f65e64f65dcd51c0756a235f1e2_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/957b39be46c507c7949a59e09d517107_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/7694cc962421085180149618fa8638ff_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/8190548e74ca74cd79921897ebe78252_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/32e5ac518a46755c2fab839c11ba353f_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/552af0047051f642f511f83f89b1b8a9_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/957b39be46c507c7949a59e09d517107 (1)_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/17299f65e64f65dcd51c0756a235f1e2_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/957b39be46c507c7949a59e09d517107_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/7694cc962421085180149618fa8638ff_副本.jpeg"
alt="" srcset="">
</div>
<div class="img">
<img src=""
data-src="/Users/hwl/Desktop/project/2023/JavaScript/js手写/23.图片懒加载/8190548e74ca74cd79921897ebe78252_副本.jpeg"
alt="" srcset="">
</div>
</div>
<script>
window.onload = function () {
const imgs = document.querySelectorAll("img[data-src]");
const box = document.querySelector(".box");
for (let i = 0; i < imgs.length; i++) {
if (i > 9) {
return;
}
imgs[i].src = imgs[i].getAttribute("data-src");
imgs[i].removeAttribute("data-src");
}
}
function lazy(fn, time) {
let key = true;
return function (...args) {
if (key) {
key = false;
setTimeout(() => {
key = true
fn.apply(this, args);
}, time);
}
}
}
function imgLoad() {
const imgs = document.querySelectorAll("img[data-src]");
for (let i = 0; i < imgs.length; i++) {
const top = imgs[i].getBoundingClientRect().top;
if (top < window.innerHeight) {
imgs[i].src = imgs[i].getAttribute("data-src");
imgs[i].removeAttribute("data-src");
} else {
return;
}
}
}
window.onscroll = lazy(imgLoad,100);
</script>
</body>
</html>
24.单例莫斯、观察者模式、发布订阅模式 ???
function gongchang(){
let temp = null;
return function(){
if(!temp){
temp = {};
}
return temp;
}
}
const fn = gongchang();
const obj1 = fn();
const obj2 = fn();
const obj3 = fn();
console.log(obj1 === obj2,obj1 === obj3);
class Observer{
constructor(name){
this.name = name;
}
getState(state){
console.log(`${this.name}知道宝宝状态变为${state}`);
}
}
class Watcher{
constructor(){
this.state = "睡觉";
this.os = [];
}
addObserver(o){
this.os.push(o);
}
setState(val){
this.state = val;
for(let i = 0;i < this.os.length;i++){
this.os[i].getState(this.state);
}
}
}
const father = new Observer("爸爸");
const mather = new Observer("妈妈");
const w = new Watcher();
w.addObserver(father);
w.addObserver(mather);
w.setState("吃饭");
class EventEmitter{
constructor(){
this.emitter = {}
}
on(name,callback){
if(!this.emitter[name]){
this.emitter[name] = [];
}
this.emitter[name].push(callback);
}
emit(name,...args){
for(let i = 0;i < this.emitter[name].length;i++){
this.emitter[name][i](...args);
}
}
}
const emitter = new EventEmitter();
emitter.on("one",function(a,b,c){
console.log(a+b+c);
})
emitter.on("one",function(a,b){
console.log(a-b);
})
emitter.on("two",function(a,b){
console.log(a*b);
})
emitter.emit("one",1,2,3);
emitter.emit("two",4,5);