1. let obj = {
  2. name: ''
  3. }
  4. function observe(obj) {
  5. if(typeof obj !== 'object') return;
  6. for(let key in obj){
  7. defineReactive(obj, key, obj[key])
  8. observe(obj[key]
  9. }
  10. }
  11. function defineReactive(target, property, value){
  12. Object.defineProperty(target, property, {
  13. get() {
  14. el.value = value // 读取的时候改变 输入框 的值
  15. console.log(newValue)
  16. return value
  17. }
  18. set(newValue) {
  19. el.value = newValue // 设置的时候改变 输入框 的值
  20. }
  21. })
  22. }
  23. observe(obj)
let dog = {
    name: '小黄',
  firends: [{
      name: '小红'
    }]
}

let proxy = new Proxy(dog, {
  get(target, property){
    console.log('被监听到了')
    return target[property]
  },

  set(target, property, value){
    console.log('set 被监听到了 set')
      target[property] = value
    }
})

深拷贝

function deepCopy(target){
  var obj = {}

  for(var i in target){
    if(typeof target[i] == 'object'){
      obj[i] = deepClone(target[i])
    } else {
        obj[i] = target[i]
    }
  }

  return obj;
}

retry

function fetchData(){
  return new Promise(() => {
    setTimeout( () => {
      reject('network error')
    }, 5000) 
  })
}

// 尝试3次,每次间隔 100
retry(fetch, 3, 100)

function retry(fetchFunction, times, timer){
  while(times){
    setTimeout( () => {
      fetchFunction()
    }, timer)
    times--;
  }
}


function retry(fetchFunction, times, timer){
  return new Promise((resolve, reject) => {

    function attempt(){
      fetchFunction.then().catch(function(){
        if(times === 0){
          reject(err)
        } else {
          setTimeout( () => {
            attempt()
          }, timer)
          times--;
        }
      })
    }

    attempt()
  })
}

手写 call、apply、bind、

var obj1 = {
  name: '猫',
  age: 1,
  getName: function(age){
    console.log('this name is', this.name, age)
  }

}

var obj2 = {
  name: '狗',
  age: 2,
  getName: function(age){
    console.log('this name is', this.name, age)
  }
}

console.log(obj1.getName.call(obj2, 4))
console.log(obj1.get)

Function.propety.myCall = function(context){
  const ctx = context || window;

  ctx.func = this;

  // 处理参数
  const args = Array.from(arguements).slice(1)

  const res = args.length > 1 ? ctx.func(args) : ctx.func();

  delete ctx.func;

  return res;
}


Function.property.myApply = function(context){
  const ctx = context || window;

  ctx.func = this;

  // 处理参数
  const res = arguements[1] ? ctx.func(...arguement[1]) : ctx.func()

  delete ctx.func;

  return res;
}

Function.property.myBind = function(context){
  const ctx = JSON.parse(JSON.stringify(context))

  ctx.func = this;

  const args = Array.form(arguments).slice(1);

  return function(){
    // 处理参数,将参数合并
    const allArgs = args.concat(Array.form(arguments))
    return allArgs.length > 0 ? ctx.func(...allArgs) : ctx.func()
  }
}


Function.property.myBind = function(context){
  const _this = this;

  return function(){
    const args = Array.from(arguments).slice(1)
      return _this.apply(context, args.concat([...arguments])
  }
}

// 使用 new 创建的构造函数的指向会变
// this instanceof bindFn 说明这是new出来的实例,指向这个实例, 否则指向context


// 绑定原型 在原型链上创建的函数 bind 返回的函数不能调用,
// 绑定原型
  bindFn.prototype = self.prototype;

// 出现问题就是会修改原型链,修改原有原型的方法
// 解决方法其实很简单,创建一个新方法proFn(),来进行原型绑定,
// 也就是实现继承的几种方式中的原型式继承,
// 然后我们把这个新方法的实例对象绑定到我们的绑定函数的原型中

Function.prototype.myBind = function(context) {
  if (typeof this !== "function") {
      throw new Error("不是一个函数");
  }
  const self = this;
  const args1 = [...arguments].slice(1);

  const bindFn = function() {
    const args2 = [...arguments];

      return self.apply(this instanceof bindFn ? this : context, args1.concat(args2));
  }

  // 绑定原型
  function proFn() {}  // 创建新方法
  proFn.prototype = self.prototype; // 继承原型
  bindFn.prototype = new proFn();   // 绑定原型

  return bindFn;
}

继承

var SuperClass = function(){
  this.info = {
    name: 'father'
  }

  this.superValue = function(){
    console.log('this name is', this.info.name)
  }
}

SuperClass.prototype.getSuperName = function(){
  return this.superValue()
}

var SubClass = function(){
  this.info = {
    name: 'son'
     }

  this.subValue = function(){
    console.log('this name is', name)
  }
}

SubClass.prototype = new SuperClass();
SubClass.prototype.getSubName = function(){
     return this.subValue()
}

var super1 = new SuperClass();
var sub1 = new SubClass();

sub1.getSuperName()


var inherits = function(Child, Parent){
  var F = function(){}
  F.prototype = Parent.prototype;
  Child.prototype = new F();
  Child.prototype.constructor = Child
};

var SuperClass = function(){
  this.info = {
    name: 'father'
  }

  this.superValue = function(){
    console.log('this name is', this.info.name)
  }
}

SuperClass.prototype.getValue = function(){
  return this.superValue()
}

var SubClass = function(){
  SuperClass.call(this)
}

inherits(SubClass, SuperClass)