第十九天


(题目来源: 前端每日知识3+1)

Javascript题目

  • 正则规则的熟悉、prototype和proto属性的区别和联系、手撕new 构造函数

问题解答

  1. /*
  2. 地区: ([1-6][1-9]|50)\d{4} // 补充重庆地区50
  3. 年的前两位: (18|19|20) 1800-2399
  4. 年的后两位: \d{2}
  5. 月份:((0[1-9])|10|11|12)
  6. 天数: (([0-2][1-9])|10|20|30|31) 闰年不能禁止29+
  7. 三位顺序码: \d{3}
  8. */
  9. function checkedID(str) {
  10. let reg18 = /^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/ // 18位
  11. let reg15 = /^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}$/ //15位
  12. // return reg.test(str)
  13. return str.match(reg18)
  14. }
  15. console.log(checkedID('14338119001211003X'));
  1. // 验证中文 4e00-9fa5
  2. function checkedID(str) {
  3. let reg = /^[\u4e00-\u9fa5]+$/
  4. // return reg.test(str)
  5. return str.match(reg)
  6. }
  7. console.log(checkedID('你好'));

题目:正则规则的熟悉、prototype和proto属性的区别和联系、手撕new 构造函数 - 图1

Javascript题目1

你对new操作符的理解是什么? 手动实现一个new方法

问题解答1

  1. function _new(Fn, ...arg) {
  2. const obj = Object.create(Fn.prototype);
  3. const obj1 = Fn.apply(obj, arg);
  4. return obj1 instanceof Object ? obj1 : obj;
  5. }

解题思路1

  1. 创建新对象
  2. 新对象原型[[prototype]] = 构造函数prototype
  3. this 指向新对象
  4. 执行构造函数
  5. 如果构造函数返回非空对象,就返回这个对象引用,不然返回创建的新对象

知识扩展

  • Object.create()方法是建立一个空对象他有两个参数, 第一个参数是在原型上新建对象, 第二个参数是在实例上创建对象; 第一个参数是必选的, 第二个参数是可选的
  • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上.
  1. Object.prototype.age = 'zs'
  2. function fn() {
  3. this.a = '1';
  4. this.b = '2'
  5. this.fn2 = function() {}
  6. }
  7. function fn1() {}
  8. fn1.prototype = new fn() // new一个fn函数 将该实例方法 放到fn1的原型上
  9. console.log(fn1.prototype); // fn的实例
  10. fn.prototype.a = 'ls' //如果原型的属性和实例的对象相同的时候,优先实例属性;如果想覆盖原型中的属性 使用constructor 指向原来的函数对象
  11. fn.prototype = {
  12. constructor: fn,
  13. a: 'ls1'
  14. }
  15. let f1 = new fn()
  16. console.log(f1);
  17. console.log(f1.__proto__); //{a: "ls", constructor: ƒ}
  18. console.log(f1.a); // ls
  19. console.log(f1 instanceof fn); // true
  20. console.log(f1 instanceof fn1); //fasle
  21. let b = new fn();
  22. // fn.prototype = '3'
  23. console.log(f1.age); // zs
  24. console.log(b.a); //1
  25. console.log(fn1.prototype);
  26. console.log(f1.__proto__ == fn1.prototype); //false
  27. console.log(f1.__proto__ == fn.prototype); //true
  28. console.log(Object.prototype == fn.prototype.__proto__); //true
  29. // 总结:函数对象有prototype属性,实例对象的__proto__属性和构造它的原型属性是相同的,实例对象的__proto__指向构造函数的原型;函数的原型对象和对象的原型对象相同,而函数的原型对象的最后指向为null,空对象

** 手撕new构造函数

  1. /**
  2. * new 函数原理:
  3. * 创建一个对象
  4. * 将对象的原型指向其构造函数的原型
  5. * 将构造函数的this指向指向该函数
  6. * 判断该构造函数是否返回非空对象,如果返回则返回这个对象的引用否则返回一个空的对象
  7. */
  8. function _new() {
  9. let obj = {};
  10. obj.__proto__ = [...arguments][0].prototype;
  11. let res = [...arguments][0].apply(obj, Array.prototype.slice.call(arguments, 1))
  12. console.log(res);
  13. console.log(res instanceof Object);
  14. return res instanceof Object ? res : obj
  15. }
  16. function fn() {
  17. this.a = arguments[0];
  18. this.b = arguments[1];
  19. }
  20. // console.log();
  21. let a = _new(fn, '1', '2');
  22. console.log(a.a); // 1
  23. // 使用构造函数的方法
  24. let b = new fn('1');
  25. console.log(b.a); //1
  • 第二种方法使用create方法
  1. function _new(Fn, ...arg) {
  2. const obj = Object.create(Fn.prototype); // 使用crete的方法, 第一个参数是在原型上新建对象, 第二个参数是在实例上创建对象
  3. const obj1 = Fn.apply(obj, arg);
  4. console.log(obj1); // undefined
  5. console.log(obj); // fn {a: "1", b: "2"}
  6. return obj1 instanceof Object ? obj1 : obj;
  7. }
  8. function fn() {
  9. this.a = arguments[0];
  10. this.b = arguments[1];
  11. }
  12. // console.log();
  13. let a = _new(fn, '1', '2');
  14. console.log(a.a); // 1
  15. // 使用构造函数的方法
  16. let b = new fn('1');
  17. console.log(b.a); //1

proto和prototype属性