第十九天
(题目来源: 前端每日知识3+1)
Javascript题目
- 正则规则的熟悉、prototype和proto属性的区别和联系、手撕new 构造函数
问题解答
/*地区: ([1-6][1-9]|50)\d{4} // 补充重庆地区50年的前两位: (18|19|20) 1800-2399年的后两位: \d{2}月份:((0[1-9])|10|11|12)天数: (([0-2][1-9])|10|20|30|31) 闰年不能禁止29+三位顺序码: \d{3}*/function checkedID(str) {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位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位// return reg.test(str)return str.match(reg18)}console.log(checkedID('14338119001211003X'));
// 验证中文 4e00-9fa5function checkedID(str) {let reg = /^[\u4e00-\u9fa5]+$/// return reg.test(str)return str.match(reg)}console.log(checkedID('你好'));

Javascript题目1
你对new操作符的理解是什么? 手动实现一个new方法
问题解答1
function _new(Fn, ...arg) {const obj = Object.create(Fn.prototype);const obj1 = Fn.apply(obj, arg);return obj1 instanceof Object ? obj1 : obj;}
解题思路1
创建新对象新对象原型[[prototype]] = 构造函数prototypethis 指向新对象执行构造函数如果构造函数返回非空对象,就返回这个对象引用,不然返回创建的新对象
知识扩展
Object.create()方法是建立一个空对象他有两个参数, 第一个参数是在原型上新建对象, 第二个参数是在实例上创建对象; 第一个参数是必选的, 第二个参数是可选的instanceof运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上.
Object.prototype.age = 'zs'function fn() {this.a = '1';this.b = '2'this.fn2 = function() {}}function fn1() {}fn1.prototype = new fn() // new一个fn函数 将该实例方法 放到fn1的原型上console.log(fn1.prototype); // fn的实例fn.prototype.a = 'ls' //如果原型的属性和实例的对象相同的时候,优先实例属性;如果想覆盖原型中的属性 使用constructor 指向原来的函数对象fn.prototype = {constructor: fn,a: 'ls1'}let f1 = new fn()console.log(f1);console.log(f1.__proto__); //{a: "ls", constructor: ƒ}console.log(f1.a); // lsconsole.log(f1 instanceof fn); // trueconsole.log(f1 instanceof fn1); //faslelet b = new fn();// fn.prototype = '3'console.log(f1.age); // zsconsole.log(b.a); //1console.log(fn1.prototype);console.log(f1.__proto__ == fn1.prototype); //falseconsole.log(f1.__proto__ == fn.prototype); //trueconsole.log(Object.prototype == fn.prototype.__proto__); //true// 总结:函数对象有prototype属性,实例对象的__proto__属性和构造它的原型属性是相同的,实例对象的__proto__指向构造函数的原型;函数的原型对象和对象的原型对象相同,而函数的原型对象的最后指向为null,空对象
** 手撕new构造函数
/*** new 函数原理:* 创建一个对象* 将对象的原型指向其构造函数的原型* 将构造函数的this指向指向该函数* 判断该构造函数是否返回非空对象,如果返回则返回这个对象的引用否则返回一个空的对象*/function _new() {let obj = {};obj.__proto__ = [...arguments][0].prototype;let res = [...arguments][0].apply(obj, Array.prototype.slice.call(arguments, 1))console.log(res);console.log(res instanceof Object);return res instanceof Object ? res : obj}function fn() {this.a = arguments[0];this.b = arguments[1];}// console.log();let a = _new(fn, '1', '2');console.log(a.a); // 1// 使用构造函数的方法let b = new fn('1');console.log(b.a); //1
- 第二种方法使用create方法
function _new(Fn, ...arg) {const obj = Object.create(Fn.prototype); // 使用crete的方法, 第一个参数是在原型上新建对象, 第二个参数是在实例上创建对象const obj1 = Fn.apply(obj, arg);console.log(obj1); // undefinedconsole.log(obj); // fn {a: "1", b: "2"}return obj1 instanceof Object ? obj1 : obj;}function fn() {this.a = arguments[0];this.b = arguments[1];}// console.log();let a = _new(fn, '1', '2');console.log(a.a); // 1// 使用构造函数的方法let b = new fn('1');console.log(b.a); //1
