第十九天
(题目来源: 前端每日知识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-9fa5
function 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]] = 构造函数prototype
this 指向新对象
执行构造函数
如果构造函数返回非空对象,就返回这个对象引用,不然返回创建的新对象
知识扩展
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); // ls
console.log(f1 instanceof fn); // true
console.log(f1 instanceof fn1); //fasle
let b = new fn();
// fn.prototype = '3'
console.log(f1.age); // zs
console.log(b.a); //1
console.log(fn1.prototype);
console.log(f1.__proto__ == fn1.prototype); //false
console.log(f1.__proto__ == fn.prototype); //true
console.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); // undefined
console.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