日常生活的交流与学习

首页 新随笔 联系 管理

C:\Users\Administrator\Desktop\手写\01_instanceOf.js

function instance_of(target, origin) {
  let targetP = target.__proto__;
  let originP = origin.prototype;
  while (true) {
    if (targetP === originP) return true;
    if (targetP === null) return false;
    targetP = targetP.__proto__;
  }
}

console.log([1] instanceof Array);
console.log(instance_of([1], Array));
console.log(instance_of([1], Object));
console.log(instance_of([1], Map));

C:\Users\Administrator\Desktop\手写\02_模拟new关键字.js

let arr = objectFactory(Array, 'cxk', '18');
console.log(arr);

function objectFactory() {
  // 创建一个权限的对象
  const obj = new Object();
  // 取出参数的第一项,为了得到构造函数
  const Constructor = [].shift.call(arguments);
  // 对象隐式原型指向构造器的显示原型
  obj.__proto__ = Constructor.prototype;
  // arguments经过前面的shift方法,实际上已经少了第一个参数
  const ret = Constructor.apply(obj, arguments);
  // 如果构造函数返回时object,则创建成功返回对象
  return typeof ret === 'object' ? ret : obj;
}

C:\Users\Administrator\Desktop\手写\03_继承.js

function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.eating = function () {
  console.log('I am eating');
};

function Student(name, age, grade) {
  Person.call(this, name, age);
  this.grade = grade;
}

// 修改子类构造函数的 显示原型,为父类的一个实例对象,为的是使用父类原型对象中的方法
// Student.prototype = new Person();
Student.prototype = Object.create(Person.prototype);
// 子类原型对象,要指会原来的子类构造函数本身
Student.prototype.constructor = Student;

Student.prototype.study = function () {
  console.log('I am studying');
};

const stu = new Student('Alice', 19, '一年级');
console.log(stu);
stu.eating();

C:\Users\Administrator\Desktop\手写\04_继承_class关键字.js

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  eating() {
    console.log('I am eating');
  }
}

class Student extends Person {
  constructor(name, age, grade) {
    super(name, age);
    this.grade = grade;
  }
  studying() {
    console.log('I am studying');
  }
}

const stu = new Student('Alice', 19, '一年级');
console.log(stu);
stu.eating();

C:\Users\Administrator\Desktop\手写\05_手写call函数.js

Function.prototype.myCall = function (context, ...args) {
  let cxt = context || window;
  //将当前被调用的方法定义在cxt.func上.(为了能以对象调用形式绑定this)
  //新建一个唯一的Symbol变量避免重复
  let func = Symbol();
  // this 表示前面发起调用的那个函数对象
  cxt[func] = this;
  console.log(args);
  args = args ? args : [];
  //以对象调用形式调用func,此时this指向cxt 也就是传入的需要绑定的this指向
  const res = args.length > 0 ? cxt[func](...args) : cxt[func]();
  //删除该方法,不然会对传入对象造成污染(添加该方法)
  delete cxt[func];
  // return res 是为了拿到返回值,万一有的函数有返回值呢
  return res;
};

const obj = { name: 'Alice' };
function foo(value1, value2) {
  console.log('this is foo ↓↓↓↓↓' + value1 + value2);
  console.log(this);
  return '我是返回值';
}
foo.myCall(obj, 'hello hahahahahaha', 'heiheihei');

C:\Users\Administrator\Desktop\手写\06_手写apply方法.js

Function.prototype.myApply = function (context = window, args = []) {
  let sy = Symbol();
  context[sy] = this;
  let res = args.length > 0 ? context[sy](...args) : context[sy]();
  return res;
};

const obj = { name: 'Alice' };
function foo(value1, value2) {
  console.log('this is foo ↓↓↓↓↓' + value1, value2);
  console.log(this);
  return '我是返回值';
}
const value = foo.myApply(obj, ['hello hahahahahaha', 'heiheihei']);
console.log(value);


C:\Users\Administrator\Desktop\手写\07_手写双向绑定vue2.js

C:\Users\Administrator\Desktop\手写\08_手写数据双向绑定vue3.js

let obj = {
  name: '55',
};
proxyObj = new Proxy(obj, {
  get: function (target, value) {
    console.log('读取了数据');
    return target[value];
  },
  set: function (target, value, newValue) {
    target[value] = newValue;
    console.log('设置了数据');
  },
});

proxyObj.name;
proxyObj.name = 'alice';

C:\Users\Administrator\Desktop\手写\09_防抖.js

function deBounce(fn, delay) {
  let timer = null;
  return function () {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

C:\Users\Administrator\Desktop\手写\10_深拷贝.js

function isObject(value) {
  const valueType = typeof value;
  return value !== null && (valueType === 'function' || valueType === 'object');
}
function deepCopy(obj, map = new WeakMap()) {
  const newObj = obj instanceof 'Array' ? [] : {};
  if (!isObject(obj)) return obj;
  if (map.has(obj)) return map.get(obj);
  map.set(obj, newObj);
  for (let key of obj) {
    newObj[key] = deepCopy(obj[key], map);
  }
}

C:\Users\Administrator\Desktop\手写\11_二叉树的遍历.js

/**
 * 递归法前序遍历
 */
function dfsPreorderByRcs(tree) {
  const output = [];

  const visitLoop = (node) => {
    if (node) {
      // 先搜索出根节点的值,push进结果列表
      output.push(node.data);
      // 访问左子节点树,左子节点开始作为根节点进行下一轮递归
      visitLoop(node.left);
      // 同上述,递归遍历右子节点
      visitLoop(node.right);
    }
  };
  
  visitLoop(tree);
  return output;
}

console.log('递归法DFS(前序): ', dfsPreorderByRcs(tree));
// 递归法DFS(前序):  [ 1, 2, 4, 8, 9, 5, 10, 11, 3, 6, 12, 7 ]

C:\Users\Administrator\Desktop\手写\12_生成器模拟async和await.js

function requestData() {
  return new Promise((resolve, reject) => {
    resolve('11110000');
  });
}

function* request() {
  const data = yield requestData();
  console.log('1__' + data);
  const data2 = yield requestData();
  console.log('2__' + data2);
  return 'ending';
}

// const gen = request();

// const genData = gen.next();
// console.log(genData);

// genData.value.then((res) => {
//   const genData2 = gen.next(res);
//   console.log(genData2);

//   genData2.value.then((res) => {
//     const genData3 = gen.next(res);
//     console.log(genData3);
//   });
// });

function execGen(genFn) {
  const gen = genFn();

  const exec = (res) => {
    let genData = gen.next(res);
    if (genData.done) return genData.value;

    genData.value.then((res) => {
      exec(res);
    });
  };
  exec();
}

execGen(request);
posted on 2022-11-16 23:23  lazycookie  阅读(29)  评论(0编辑  收藏  举报