day0426

day0426

重写new

重写call

重写apply

重写bind

重写instanceof

代理拦截

defineProperty

ES5 提供了 Object.defineProperty 方法,该方法可以在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。Object.defineProperty无法监听数组变化。

Object.defineProperty(obj, prop, descriptor)
参数说明:
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性

var obj = {
    test:"hello"
}
//对象已有的属性添加特性描述
Object.defineProperty(obj,"test",{
    // 能不能被配置(删除)
configurable:true | false,
// 是否可枚举
    enumerable:true | false,
value:任意类型的值,
// 是否可写,此配置和 get/set不能同时存在
writable:true | false,
get(){},
set(value){}
});
var data = {
  name: '张三'
}

function observer(data) {
  if (typeof data !== 'object') return data
  for (let key in data) {
    defineReactive(data, key, data[key])
  }
}

function defineReactive(target, key, value) {
  observer(value)
  Object.defineProperty(target, key, {
    get() {
      return value
    },
    set(newVal) {
      if (value !== newVal) {
        value = newVal
        update(key, value)
      }
    }
  })
}

function update(key, value) {
  document.querySelectorAll(`[v-bind="${key}"]`).forEach(el => {
    if (el.tagName === 'INPUT') {
      el.value = value
    } else {
      el.innerHTML = value
    }
  })
};
// 监听
observer(data);


// 初始化
document.querySelectorAll('[v-model]').forEach(el => {
  el.addEventListener('keyup', function () {
    let prop = this.getAttribute('v-model')
    data[prop] = this.value
  })
})

Proxy

在这里插入图片描述

const obj = { name: "张三" };

const proxy = new Proxy(obj, {
  get(target, key) {
    return target[key];
  },
  set(target, key, value) {
    console.log(target, key, value)
    target[key] = value;
    return true;
  }
});
proxy.age = 10;
console.log(proxy, obj);
代理实现字符串截取
const news = [
  {
    title: "海外网深一度:气候危机“逼近灾难临界值”,中国行动振奋世界"
  },
  {
    title: "小区不准外卖员入内,杭州一外卖小哥回家被保安拦下!民警到场调解,小哥情绪崩溃"
  },
  {
    title: "网传浙江慈溪上林中学一女生教室内被多次扇耳光 当地回应:已去处置"
  }
];
const newsProxy = new Proxy(news, {
  get(target, key) {
    let title = target[key]['title'];
    target[key]['title'] = title.length > 10 ? title.substr(0, 10) + '...' : title
    return target[key]
  }
});

console.log(newsProxy[0])
双向绑定
let obj = {
  name: '张三',
}

const proxyHandler = {
  get(target, key) {

    if (typeof target[key] === "object") {
      return new Proxy(target[key], proxyHandler)
    }

    return target[key]
  },
  set(target, key, value) {
    let oldValue = target[key]
    if (oldValue !== value) {
      target[key] = value
      update(key, value)
      return true
    }
  }
}

let proxy = new Proxy(obj, proxyHandler)

function update(key, value) {
  document.querySelectorAll(`[v-bind="${key}"]`).forEach(el => {
    if (el.tagName === 'INPUT') {
      el.value = value
    } else {
      el.innerHTML = value
    }
  })
}


// 初始化时
document.querySelectorAll('[v-model]').forEach(el => {
  el.addEventListener('keyup', function () {
    let prop = this.getAttribute('v-model')
    proxy[prop] = this.value
  })
})

模块化

在这里插入图片描述
前端模块化方案:AMD[requirejs],CMD[seajs],CommonJS[nodejs]和ES6

AMD和CMD,两者的区别是前者是对于依赖的模块提前执行,而后者是延迟执行。 前者推崇依赖前置,而后者推崇依赖就近,即只在需要用到某个模块的时候再require

AMD

AMD是RequireJS在推广过程中对模块定义的规范化产出。AMD规范则是非同步加载模块,允许指定回调函数。

// 定义模块,没有依赖项
define(function () {
  function fn1() {
    return '你好fn1'
  }
  // 导出模块
  return {
    fn1
  }
})

// 定义模块有这依赖项
define(['m1'], function (m1) {
  function fn2() {
    console.log('m2模块', m1.fn1());
  };
  // 暴露模块
  return { fn2 };
})

// 入口文件
(function () {
  requirejs.config({
    // 配置js路径
    paths: {
      m1: './module/m1',
      m2: './module/m2',
      jquery: './module/jquery'
    }
  });

  requirejs(['m2', ' jquery'], function (m2) {
    m2.fn2();
    $('#box').click(function(){
      console.log(1111);
    })
  })
})()
<div id="box">点击试一下</div>
<script data-main="./main.js" src="./lib/require.js"></script>

CMD

CMD是SeaJS在推广过程中对模块定义的规范化产出。

// 没有依赖的模块
define(function (require, exports, module) {
  function fn1() {
    console.log("m1模块下面的fn1方法");
  };
  // 导出模块
  module.exports = {
    fn1
  }
})

// 有依赖的模块
define(function (require, exports, module) {
  // 导入依赖模块
  let m1 = require('./m1')
  m1.fn1()
  function fn2() {
    console.log('我是m2模块下面的fn2方法');
  }
  exports.fn2 = fn2
});

// 主入口文件
define(function (require) {
  let m2 = require('./m2')
  m2.fn2()
  let jquery = require('./jquery')

  console.log(jquery('body'));
})
// 页面
<script src="./lib/sea.js"></script>
<script>
  seajs.use('./module/main.js')
</script>

CommonJS

在这里插入图片描述

ES6模块

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值