实现一个new
new的具体步骤
- 内存中创建一个新对象
- 新建对象的 _ proto _指向构造函数的prototype
- 调用构造函数,函数的this指向新创建的对象
- 执行构造函数内部的代码(给新对象添加属性)
- 如果构造函数返回非空对象,则返回该对象,否则,返回新创建的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| function Person(age, name) { this.age = age; this.name = name; } Person.prototype.sayHello = function() { console.log(this.name); }
function myNew(fn, ...args) { const obj = Object.create(fn.prototype) const rel = fn.apply(obj,args)
return rel instanceof Object ? rel : obj } const p1 = myNew(Person, 19, 'hyz');
|
实现一个Object.create
Object.create(proto)创建一个空对象,proto为空对象的”proto“
1 2 3 4 5 6 7 8 9 10 11
| export function create(obj) { if (obj === null) { return Object.setPrototypeOf({}, null); } if (!(obj instanceof Object)) { throw new TypeError(); } return Object.setPrototypeOf({}, obj); }
|
虾皮笔试题
十分有水平的一道题,综合了new原理,原型链+instanceof原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function Person() {
} let person1 = new Person(); Person.prototype = { name: 'ee', sayName: () => {
} }
console.log('person1 instanceof Person: ', person1 instanceof Person)
console.log('person1 instanceof Object: ', person1 instanceof Object)
console.log('person1.constructor == Person: ', person1.constructor == Person)
console.log('person1.constructor == Object: ', person1.constructor == Object)
|
实现消息订阅
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| class EventCenter {
constructor(handlers=new Map()) { this.handlers = handlers; }
addEventListener(type, newHandler) { let hanlder = this.handlers.has(type); if (hanlder) { this.handlers.set(type, [...this.handlers.get(type), newHandler]) } else { this.handlers.set(type, [newHandler]); } }
dispatchEvent(type, params=[]) { const handler = this.handlers.get(type); handler && handler.forEach((callback) => { callback(...params); }) }
removeEventListener(type, delHandler) { if (!this.handlers.has(type)) { return new Errow("Unable to delete") } if (delHanlder) { const oldHandlers = this.handlers.get(type); const ind = oldHandlers.indexOf(delHandler); if (ind === -1) { return new Errow("Unable to delete") } oldHandlers.splice(ind, 1); } else { this.handlers.delete(type); } } }
|
实现一个JSONP
前端部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| function jsonp(url, options) { const { timeout } = options; return new Promise((resolve, reject) => { let funcName = `jsonp${Date.now()}`; let time = null, scriptNode; window[funcName] = function (data) { if (timeout) clearTimeout(time); resolve(data); delete window[funcName]; document.body.removeChild(scriptNode); } scriptNode = document.createElement('script'); scriptNode.src = `${url}?callback=${funcName}`; document.body.appendChild(scriptNode); time = setTimeout(() => { reject('network err, timeout') }, timeout) scriptNode.onerror = function (err) { reject(err); } }) } jsonp('http://localhost:9090/api', { callBack: 'res1', timeout: 3000 }) .then(res => { console.log('jsonp->', res); }) .catch(err => { console.log("network err!") })
|
后端部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const http = require('http'); const url = require('url'); http.createServer((req, res) => { if(req.url.includes('/api')) { let myurl = url.parse(req.url); let params = new URLSearchParams(myurl.query) let posts = ['js', 'php']; let mathodName = params.get('callback'); res.end(`${mathodName}(${JSON.stringify(posts)})`) } }) .listen(9090, () => { console.log(9090); })
|